home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / ast_text / faqs / cmplngc!.faq < prev    next >
Text File  |  1993-07-11  |  169KB  |  3,498 lines

  1. From charnel!olivea!uunet!gatech!news.ans.net!rpi!clarkson!news.clarkson.edu!cline Sat Jul 10 22:36:53 PDT 1993
  2. Article: 40541 of comp.lang.c++
  3. Newsgroups: comp.lang.c++,news.answers
  4. Path: charnel!olivea!uunet!gatech!news.ans.net!rpi!clarkson!news.clarkson.edu!cline
  5. From: cline@sun.soe.clarkson.edu (Marshall Cline)
  6. Subject: comp.lang.c++ FAQ (part 1 of 4)
  7. Message-ID: <CLINE.93Jul9063649@cheetah.clarkson.edu>
  8. Sender: news@news.clarkson.edu
  9. Nntp-Posting-Host: cheetah.ece.clarkson.edu
  10. Reply-To: cline@parashift.com (Marshall Cline)
  11. Organization: Paradigm Shift, Inc (Reuse/C++/OOD training, C++ libraries)
  12. Date: Fri, 9 Jul 1993 11:36:49 GMT
  13. Approved: news-answers-request@MIT.Edu
  14. Expires: Mon, 9 Aug 1993 10:30:14 GMT
  15. Lines: 830
  16. Xref: charnel comp.lang.c++:40541 news.answers:10205
  17.  
  18. To all:
  19.  
  20. Until Jamshid Afshar and I figure out the appropriate C++FAQ posting guidelines
  21. (ie: whether we have to continue posting it in several pieces), I decided to
  22. post the latest update in four big files (4*40k=160k) . . .
  23.  
  24. Marshall
  25.  
  26.  
  27. ==============================================================================
  28.  
  29.     Document:    Frequently-Asked-Questions for comp.lang.c++
  30.     Revision:    09-July-93
  31.  
  32.     Author:        Marshall P. Cline, Ph.D.
  33.             Paradigm Shift, Inc.
  34.             One Park St. / Norwood, NY  13668
  35.             voice: 315-353-6100
  36.             fax:   315-353-6110
  37.             email: cline@parashift.com
  38.  
  39.     Copyright:    Copyright (C), 1991-93 Marshall P. Cline, Ph.D.
  40.             Permission to copy all or part of this work is granted,
  41.             provided that the copies are not made or distributed
  42.             for resale (except nominal copying fee may be charged),
  43.             and provided that the NO WARRANTY, author-contact, and
  44.             copyright notice are retained verbatim & are displayed
  45.             conspicuously.  If anyone needs other permissions that
  46.             aren't covered by the above, please contact the author.
  47.  
  48.     NO WARRANTY:    THIS WORK IS PROVIDED ON AN "AS IS" BASIS.  THE AUTHOR
  49.             PROVIDES NO WARRANTY WHATSOEVER, EITHER EXPRESS OR
  50.             IMPLIED, REGARDING THE WORK, INCLUDING WARRANTIES WITH
  51.             RESPECT TO ITS MERCHANTABILITY OR FITNESS FOR ANY
  52.             PARTICULAR PURPOSE.
  53.  
  54.     Availability:    This is available via anonymous ftp
  55.             from: sun.soe.clarkson.edu [128.153.12.3]
  56.             in the file: pub/C++/FAQ
  57.  
  58.     Without FTP:    You can also get it by sending electronic mail:
  59.             |    To: archive-server@sun.soe.clarkson.edu
  60.             |    Subject: send C++/FAQ
  61.             This will help those who don't have ftp.
  62.  
  63.     (NOTE: I hear the mail server is down; if you have problems,
  64.      send details and I'll look into it).
  65.  
  66.     See also:    comp.lang.c's FAQ appears at the beginning of every
  67.             month in that newsgroup, and is maintained by
  68.             Steve Summit (scs@adm.mit.edu).
  69.  
  70. ==============================================================================
  71. SUBSECTION: Table of Contents
  72. ==============================================================================
  73.  
  74. PART01 -- Introduction and table of contents
  75. Table of Contents
  76. Nomenclature and Common Abbreviations
  77.  
  78. PART02 -- Environmental/managerial issues
  79. Q1: What is C++? What is OOP?
  80. Q2: What are some advantages of C++?
  81. Q3: Who uses C++?
  82. Q4: Are there any C++ standardization efforts underway?
  83. Q5: Where can I ftp a copy of the latest ANSI-C++ draft standard?
  84. Q6: Is C++ backward compatible with ANSI-C?
  85. Q7: How long does it take to learn C++?
  86.  
  87. PART03 -- Basics of the paradigm
  88. Q8: What is a class?
  89. Q9: What is an object?
  90. Q10: What is a reference?
  91. Q11: What happens if you assign to a reference?
  92. Q12: How can you reseat a reference to make it refer to a different object?
  93. Q13: When should I use references, and when should I use pointers?
  94. Q14: What are inline fns? What are their advantages? How are they declared?
  95.  
  96. PART04 -- Constructors and destructors
  97. Q15: What is a constructor?  Why would I ever use one?
  98. Q16: How can I make a constructor call another constructor as a primitive?
  99. Q17: What are destructors really for?  Why would I ever use them?
  100.  
  101. PART05 -- Operator overloading
  102. Q18: What is operator overloading?
  103. Q19: What operators can/cannot be overloaded?
  104. Q20: Can I create a `**' operator for `to-the-power-of' operations?
  105.  
  106. PART06 -- Friends
  107. Q21: What is a `friend'?
  108. Q22: Do `friends' violate encapsulation?
  109. Q23: What are some advantages/disadvantages of using friends?
  110. Q24: What does it mean that `friendship is neither inherited nor transitive'?
  111. Q25: When would I use a member function as opposed to a friend function?
  112.  
  113. PART07 -- Input/output via <iostream.h> and <stdio.h>
  114. Q26: How can I provide printing for a `class X'?
  115. Q27: Why should I use <iostream.h> instead of the traditional <stdio.h>?
  116. Q28: Printf/scanf weren't broken; why `fix' them with ugly shift operators?
  117.  
  118. PART08 -- Freestore management
  119. Q29: Does `delete ptr' delete the ptr or the pointed-to-data?
  120. Q30: Can I free() ptrs alloc'd with `new' or `delete' ptrs alloc'd w/ malloc()?
  121. Q31: Why should I use `new' instead of trustworthy old malloc()?
  122. Q32: Why doesn't C++ have a `realloc()' along with `new' and `delete'?
  123. Q33: How do I allocate / unallocate an array of things?
  124. Q34: What if I forget the `[]' when `delete'ing array allocated via `new X[n]'?
  125.  
  126. PART09 -- Debugging and error handling
  127. Q35: How can I handle a constructor that fails?
  128. Q36: How can I compile-out my debugging print statements?
  129.  
  130. PART10 -- Const correctness
  131. Q37: What is `const correctness'?
  132. Q38: Is `const correctness' a good goal?
  133. Q39: Is `const correctness' tedious?
  134. Q40: Should I try to get things const correct `sooner' or `later'?
  135. Q41: What is a `const member function'?
  136. Q42: What is an `inspector'?  What is a `mutator'?
  137. Q43: What is `casting away const in an inspector' and why is it legal?
  138. Q44: But doesn't `cast away const' mean lost optimization opportunities?
  139.  
  140. PART11 -- Inheritance
  141. Q45: What is inheritance?
  142. Q46: Ok, ok, but what is inheritance?
  143. Q47: How do you express inheritance in C++?
  144. Q48: What is `incremental programming'?
  145. Q49: Should I pointer-cast from a derived class to its base class?
  146. Q50: Derived* --> Base* works ok; why doesn't Derived** --> Base** work?
  147. Q51: Does array-of-Derived is-NOT-a-kind-of array-of-Base mean arrays are bad?
  148. Inheritance -- virtual functions
  149. Q52: What is a `virtual member function'?
  150. Q53: What is dynamic dispatch?  Static dispatch?
  151. Q54: Can I override a non-virtual fn?
  152. Q55: Why do I get the warning "Derived::foo(int) hides Base::foo(double)"?
  153. Inheritance -- conformance
  154. Q56: Can I `revoke' or `hide' public member fns inherited from my base class?
  155. Q57: Is a `Circle' a kind-of an `Ellipse'?
  156. Q58: Are there other options to the `Circle is/isnot kind-of Ellipse' dilemma?
  157. Inheritance -- access rules
  158. Q59: Why can't I access `private' things in a base class from a derived class?
  159. Q60: What's the difference between `public:', `private:', and `protected:'?
  160. Q61: How can I protect subclasses from breaking when I change internal parts?
  161. Inheritance -- constructors and destructors
  162. Q62: Why does base ctor get *base*'s virtual fn instead of the derived version?
  163. Q63: Does a derived class dtor need to explicitly call the base destructor?
  164. Inheritance -- private and protected inheritance
  165. Q64: How do you express `private inheritance'?
  166. Q65: How are `private derivation' and `containment' similar? dissimilar?
  167. Q66: Should I pointer-cast from a `privately' derived class to its base class?
  168. Q67: Should I pointer-cast from a `protected' derived class to its base class?
  169. Q68: What are the access rules with `private' and `protected' inheritance?
  170. Q69: Do most C++ programmers use containment or private inheritance?
  171.  
  172. PART12 -- Abstraction
  173. Q70: What's the big deal of separating interface from implementation?
  174. Q71: How do I separate interface from implementation in C++ (like Modula-2)?
  175. Q72: What is an ABC (`abstract base class')?
  176. Q73: What is a `pure virtual' member function?
  177. Q74: How can I provide printing for an entire hierarchy rooted at `class X'?
  178. Q75: What is a `virtual destructor'?
  179. Q76: What is a `virtual constructor'?
  180.  
  181. PART13 -- Style guidelines
  182. Q77: What are some good C++ coding standards?
  183. Q78: Are coding standards necessary?  sufficient?
  184. Q79: Should our organization determine coding standards from our C experience?
  185. Q80: Should I declare locals in the middle of a fn or at the top?
  186. Q81: What source-file-name convention is best? `foo.C'? `foo.cc'? `foo.cpp'?
  187. Q82: What header-file-name convention is best? `foo.H'? `foo.hh'? `foo.hpp'?
  188. Q83: Are there any lint-like guidelines for C++?
  189.  
  190. PART14 -- C++/Smalltalk differences and keys to learning C++
  191. Q84: Why does C++'s FAQ have a section on Smalltalk? Is this Smalltalk-bashing?
  192. Q85: What's the difference between C++ and Smalltalk?
  193. Q86: What is `static typing', and how is it similar/dissimilar to Smalltalk?
  194. Q87: Which is a better fit for C++: `static typing' or `dynamic typing'?
  195. Q88: How can you tell if you have a dynamically typed C++ class library?
  196. Q89: Will `standard C++' include any dynamic typing primitives?
  197. Q90: How do you use inheritance in C++, and is that different from Smalltalk?
  198. Q91: What are the practical consequences of diffs in Smalltalk/C++ inheritance?
  199. Q92: Do you need to learn a `pure' OOPL before you learn C++?
  200. Q93: What is the NIHCL?  Where can I get it?
  201.  
  202. PART15 -- Reference and value semantics
  203. Q94: What is value and/or reference semantics, and which is best in C++?
  204. Q95: What is `virtual data', and how-can / why-would I use it in C++?
  205. Q96: What's the difference between virtual data and dynamic data?
  206. Q97: Should class subobjects be ptrs to freestore allocated objs, or contained?
  207. Q98: What are relative costs of the 3 performance hits of allocated subobjects?
  208. Q99: What is an `inline virtual member fn'?  Are they ever actually `inlined'?
  209. Q100: Sounds like I should never use reference semantics, right?
  210. Q101: Does the poor performance of ref semantics mean I should pass-by-value?
  211.  
  212. PART16 -- Linkage-to/relationship-with C
  213. Q102: How can I call a C function `f()' from C++ code?
  214. Q103: How can I create a C++ function `f()' that is callable by my C code?
  215. Q104: Why's the linker giving errors for C/C++ fns being called from C++/C fns?
  216. Q105: How can I pass an object of a C++ class to/from a C function?
  217. Q106: Can my C function access data in an object of a C++ class?
  218. Q107: Why do I feel like I'm `further from the machine' in C++ as opposed to C?
  219.  
  220. PART17 -- Pointers to member functions
  221. Q108: What is the type of `ptr-to-member-fn'?  Is it diffn't from `ptr-to-fn'?
  222. Q109: How can I ensure `X's objects are only created with new, not on the stack?
  223. Q110: How do I pass a ptr to member fn to a signal handler,X event callback,etc?
  224. Q111: Why am I having trouble taking the address of a C++ function?
  225. Q112: How do I declare an array of pointers to member functions?
  226.  
  227. PART18 -- Container classes and templates
  228. Q113: How can I insert/access/change elements from a linked list/hashtable/etc?
  229. Q114: What's the idea behind `templates'?
  230. Q115: What's the syntax / semantics for a `function template'?
  231. Q116: What's the syntax / semantics for a `class template'?
  232. Q117: What is a `parameterized type'?
  233. Q118: What is `genericity'?
  234. Q119: How can I fake templates if I don't have a compiler that supports them?
  235.  
  236. PART19 -- Nuances of particular implementations
  237. Q120: Why don't variable arg lists work for C++ on a Sun SPARCstation?
  238. Q121: GNU C++ (g++) produces big executables for tiny programs; Why?
  239. Q122: Is there a yacc-able C++ grammar?
  240. Q123: What is C++ 1.2?  2.0?  2.1?  3.0?
  241. Q124: How does the lang accepted by cfront 3.0 differ from that accepted by 2.1?
  242. Q125: Why are exceptions going to be implemented after templates? Why not both?
  243. Q126: What was C++ 1.xx, and how is it different from the current C++ language?
  244.  
  245. PART20 -- Miscellaneous technical and environmental issues
  246. Miscellaneous technical issues:
  247. Q127: Why are classes with static data members getting linker errors?
  248. Q128: What's the difference between the keywords struct and class?
  249. Q129: Why can't I overload a function by its return type?
  250. Q130: What is `persistence'?  What is a `persistent object'?
  251. Miscellaneous environmental issues:
  252. Q131: Is there a TeX or LaTeX macro that fixes the spacing on `C++'?
  253. Q132: Where can I access C++2LaTeX, a LaTeX pretty printer for C++ source?
  254. Q133: Where can I access `tgrind', a pretty printer for C++/C/etc source?
  255. Q134: Is there a C++-mode for GNU emacs?  If so, where can I get it?
  256. Q135: What is `InterViews'?
  257. Q136: Where can I get OS-specific questions answered (ex:BC++,DOS,Windows,etc)?
  258. Q137: Why does my DOS C++ program says `Sorry: floating point code not linked'?
  259.  
  260. ==============================================================================
  261. SUBSECTION: Nomenclature and Common Abbreviations
  262. ==============================================================================
  263.  
  264. Here are a few of the abbreviations/etc used in this article:
  265.  
  266.     term    meaning
  267.     ====    ===========
  268.     ctor    constructor
  269.     copy-ctor    copy constructor (also `X(const X&)', pronounced `X-X-ref')
  270.     dtor    destructor
  271.     fn        function
  272.     fns        functions
  273.     ptr        pointer, a C/C++ construct declared by:  int * p;
  274.     ref        reference, a C++ construct declared by:  int & r;
  275.     const    a C++ keyword which is short for `constant'
  276.     OO        object-oriented
  277.     OOP        object-oriented programming
  278.     OOPL    object-oriented programming language
  279.     method    an alternate term for `member function'
  280.     message    an alternate term for `invoking a member function'
  281.     NULL    the `zero' or `empty' pointer (`NULL' in C, `0' in C++)
  282.  
  283. ==============================================================================
  284.  
  285.         ****  PART 02 -- Environmental/managerial issues  ****
  286.  
  287. ==============================================================================
  288.  
  289. Q1: What is C++? What is OOP?
  290.  
  291. C++ can be used simply as `a better C', but that is not its real advantage.
  292. C++ is an object-oriented programming language (OOPL).  OOPLs appear to be the
  293. current `top shelf' in the development of programming languages that can manage
  294. the complexity of large software systems.
  295.  
  296. Some OOP hype: software engineering is `failing' to provide the current users
  297. demands for large, complex software systems.  But this `failure' is actually
  298. due to SE's *successes*.  In other words, structured programming was developed
  299. to allow software engineers to design/build HUGE software systems (that's a
  300. success).  When users saw how successful these systems were, they said, `More
  301. --- give me MOOORRRREEEE'.  They wanted more power, more features, more
  302. flexibility.  100K line systems are almost commonplace nowadays, and they still
  303. want more.  Structured programming techniques, some say, begin to break down
  304. around 100K lines (the complexity gives the design team too many headaches, and
  305. fixing one problem breaks 5 more, etc).  So pragmatics demands a better
  306. paradigm than structured programming.  Hence OO-design.
  307.  
  308. ==============================================================================
  309.  
  310. Q2: What are some advantages of C++?
  311.  
  312. GROWTH OF C++: C++ is by far the most popular OOPL.  Knowing C++ is a good
  313. resume-stuffer.  But don't just use it as a better C, or you won't be using all
  314. its power.  Like any quality tool, C++ must be used the way it was designed to
  315. be used.  The number of C++ users is doubling every 7.5 to 9 months.  This
  316. exponential growth can't continue forever(!), but it is becoming a significant
  317. chunk of the programming market (it's already the dominant OOPL).
  318.  
  319. ENCAPSULATION: For those of you who aren't on a team constructing software
  320. mega-systems, what does C++ buy you?  Here's a trivial example.  Suppose you
  321. want a `Foible' data type.  One style of doing this in `C' is to create a
  322. `Foible.h' file that holds the `public interface', then stick all the
  323. implementation into a `Foible.c' file.  Encapsulation (hiding the details) can
  324. be achieved by making all data elements in `Foible.c' be `static'.  But that
  325. means you only get one `Foible' in the entire system, which is ok if `Foible'
  326. is a Screen or perhaps a HardDisk, but is lousy if Foible is a complex number
  327. or a line on the screen, etc.  Read on to see how it's done in `C' vs `C++'.
  328.  
  329. MULTIPLE INSTANCES: The `C' solution to the above `multiple instances' problem
  330. is to wrap all the data members in a struct (like a Pascal `record'), then pass
  331. these structs around as if they were the `ComplexNumber' or whatever.  But this
  332. loses encapsulation.  Other techniques can be devised which allow both multiple
  333. instances and encapsulation, however these lose on other accounts (ex:
  334. typedef'ing `Foible' to be `void*' loses type safety, and wrapping a `void*' in
  335. the Foible struct loses an extra layer of indirection).  So the `module'
  336. technique loses multiple instantiations, but the `struct' technique loses
  337. encapsulation.  C++ allows you to combine the best of both worlds - you can
  338. have what amount to structs whose data is hidden.
  339.  
  340. INLINE FUNCTION CALLS: The `encapsulated C' solution above requires a function
  341. call to access even trivial fields of the data type (if you allowed direct
  342. access to the struct's fields, the underlying data structure would become
  343. virtually impossible to change since too many pieces of code would *rely* on it
  344. being the `old' way).  Function call overhead is small, but can add up.  C++
  345. provides a solution by allowing function calls to be expanded `inline', so you
  346. have: the (1) safety of encapsulation, (2) convenience of multiple instances,
  347. (3) speed of direct access.  Furthermore the parameter types of these inline
  348. functions are checked by the compiler, an improvement over C's #define macros.
  349.  
  350. OVERLOADING OPERATORS: For the `ComplexNumber' example, you want to be able to
  351. use it in an expression `just as if' it was a builtin type like int or float.
  352. C++ allows you to overload operators, so you can tell the compiler what it
  353. means for two complex numbers to be added, subtracted, multiplied, etc.  This
  354. gives you: z0 = (z1 + z2) * z3 / z4; Furthermore you might want string1+string2
  355. to mean string concatenation, etc.  One of the goals of C++ is to make user
  356. defined types `look like' builtin types.  You can even have `smart pointers',
  357. which means a pointer `p' could actually be a user defined data type that
  358. `points' to a disk record (for example).  `Dereferencing' such a pointer (ex:
  359. i=*p;) means ``seek to the location on disk where p `points' and return its
  360. value''.  Also statements like p->field=27; can store things on disk, etc.  If
  361. later on you find you can fit the entire pointed-to data structure in memory,
  362. you just change the user-defined pseudo-pointer type and recompile.  All the
  363. code that used these `pseudo pointers' doesn't need to be changed at all.
  364.  
  365. INHERITANCE: We still have just scratched the surface.  In fact, we haven't
  366. even gotten to the `object-oriented' part yet!  Suppose you have a Stack data
  367. type with operations push, pop, etc.  Suppose you want an InvertableStack,
  368. which is `just like' Stack except it also has an `invert' operation.  In `C'
  369. style, you'd have to either (1) modify the existing Stack module (trouble if
  370. `Stack' is being used by others), or (2) copy Stack into another file and text
  371. edit that file (results in lots of code duplication, another chance to break
  372. something tricky in the Stack part of InvertableStack, and especially twice as
  373. much code to maintain).  C++ provides a much cleaner solution: inheritance.
  374. You say `InvertableStack inherits everything from Stack, and InvertableStack
  375. adds the invert operation'.  Done.  Stack itself remains `closed' (untouched,
  376. unmodified), and InvertableStack doesn't duplicate the code for push/pop/etc.
  377.  
  378. POLYMORPHISM: The real power of OOP isn't just inheritance, but is the ability
  379. to pass an InvertableStack around as if it actually were a Stack.  This is
  380. `safe' since (in C++ at least) the is-a relation follows public inheritance
  381. (ie: a InvertableStack is-a Stack that can also invert itself).  Polymorphism
  382. is easiest to understand from an example, so here's a `classic': a graphical
  383. draw package might deal with Circles, Squares, Rectangles, general Polygons,
  384. and Lines.  All of these are Shapes.  Most of the draw package's functions need
  385. a `Shape' parameter (as opposed to some particular kind of shape like Square).
  386. Ex: if a Shape is picked by a mouse, the Shape might get dragged across the
  387. screen and placed into a new location.  Polymorphism allows the code to work
  388. correctly even if the compiler only knows that the parameter is a `Shape'
  389. without knowing the exact kind of Shape it is.  Furthermore suppose the
  390. `pick_and_drag(Shape*) function just mentioned was compiled on Tuesday, and on
  391. Wednesday you decide to add the Hexagon shape.  Strange as it sounds,
  392. pick_and_drag() will still work with Hexagons, even though the Hexagon didn't
  393. even exist when pick_and_drag() was compiled!!  (it's not really `amazing' once
  394. you understand how the C++ compiler does it -- but it's still very convenient!)
  395.  
  396. ==============================================================================
  397.  
  398. Q3: Who uses C++?
  399. A: Lots and lots of companies and government sites.  Lots.
  400. Statistically, 20 to 30 people will consider themselves to be new C++
  401. programmers before you finish reading the responses to these FAQs.
  402.  
  403. ==============================================================================
  404.  
  405. Q4: Are there any C++ standardization efforts underway?
  406. A: Yes; ANSI (American) and ISO (International) groups are working closely with
  407. each other.
  408.  
  409. `X3J16' is the name of the ANSI-C++ committee.
  410.  
  411. `WG21' is the name of ISO's C++ standards group.
  412.  
  413. The committees are using the `ARM' as a base document:
  414.     `Annotated C++ Reference Manual', Ellis and Stroustrup, Addison/Wesley.
  415.     ISBN 0-201-51459-1
  416.  
  417. The major players in the ANSI/ISO C++ standards process includes just about
  418. everyone:
  419.  
  420. AT&T, IBM, DEC, HP, Sun, MS, Borland, Zortech, Apple, OSF, <add your favorite
  421. here>, ... and a lot of users and smaller companies.  About 70 people attend
  422. each ANSI C++ meeting.  People come from USA, UK, Japan, Germany, Sweden,
  423. Denmark, France, ... (all have `local' committees sending official
  424. representatives and conducting `local' meetings).
  425.  
  426. Optimistically the standard might be finished by 1995-6 time frame (this is
  427. fast for a proper standards process).
  428.  
  429. ==============================================================================
  430.  
  431. Q5: Where can I ftp a copy of the latest ANSI-C++ draft standard?
  432. A: You can't.  ANSI standards and/or drafts are NOT available in machine
  433. readable form.
  434.  
  435. You can get a paper copy by sending a request to:
  436.     Standards Secretariat
  437.     CBEMA
  438.     311 First St NW, Suite 500
  439.     Washington, DC  20001
  440. Ask for the latest version of `Working Paper for Draft Proposed American
  441. National Standard for Information Systems -- Programming Language C++'.
  442.  
  443. ==============================================================================
  444.  
  445. Q6: Is C++ backward compatible with ANSI-C?
  446. A: Almost. C++ is as close as possible to compatible with ANSI-C but no closer.
  447. In practice, the major difference is that C++ requires prototypes, and that
  448. `f()' declares a function that takes no parameters, while ANSI-C rules state
  449. that `f()' declares a function that takes any number of parameters of any type.
  450. There are some very subtle differences as well, like the sizeof a char literal
  451. being equal to the sizeof a char (in ANSI-C, sizeof('x') is the sizeof an int).
  452. Structure `tags' are in the same namespace as other names in C++, but C++ has
  453. some warts to take care of backward compatibility here.
  454.  
  455. ==============================================================================
  456.  
  457. Q7: How long does it take to learn C++?
  458. A: I and others teach standard industry `short courses' (for those not familiar
  459. with these, you pack a university semester course into one 40hr work-week), and
  460. have found them successful.  However mastery takes experience, and there's no
  461. substitute for time.  Laboratory time is essential for any OOP course, since it
  462. allows concepts to `gel'.
  463.  
  464. Generally people start out wondering why the company has devoted a full 5 days
  465. to something as trivial as another programming language.  Then about half way
  466. through, they realize they're not being taught just a new syntax, but an
  467. entirely different way of thinking and programming and designing and . . . .
  468. Then they begin to feel dumb, since they can't quite grasp what is being said.
  469. Then they get mad and wonder why the course isn't taught in two or three weeks
  470. instead.  Finally about Wednesday afternoon the lights go `clink', and their
  471. faces brighten, and they `get it'.  By Friday, they've had numerous laboratory
  472. `experiments' and they've seen both sides of reusable components (both how to
  473. code *from* reuse, and how to code *for* reuse).  It's different in every time
  474. I teach, but the `reuse' aspect is rewarding, since it has a large potential to
  475. improve software production's overall economics.
  476.  
  477. It takes 9 months to `master' C++/OOP.  Less if there is already a body of
  478. experts and code that programmers have regular access to, more if there isn't a
  479. `good' general purpose C++ class library available.
  480.  
  481. ==============================================================================
  482.  
  483.         ****  PART 03 -- Basics of the paradigm  ****
  484.  
  485. ==============================================================================
  486.  
  487. Q8: What is a class?
  488. A: A class defines a data type, much like a struct would be in C.  In a CompSci
  489. sense, a type consists of two things: a set of values *and* a set of operations
  490. which operate on those values.  Thus `int' all by itself isn't a true `type'
  491. until you add operations like `add two ints' or `int*int', etc.  In exactly the
  492. same way, a `class' provides a set of (usually `public') operations, and a set
  493. of (usually non-public) data bits representing the abstract values that
  494. instances of the type can have.  From a C language perspective, a `class' is a
  495. `struct' whose members default to `private'.
  496.  
  497. ==============================================================================
  498.  
  499. Q9: What is an object?
  500. A: An object is a region of storage with associated semantics.  After the
  501. declaration `int i;', we say that `i is an object of type int'.  In C++/OOP,
  502. `object' is usually used to mean `an instance of a class'.  Thus a class
  503. defines the behavior of possibly many objects (instances).
  504.  
  505. ==============================================================================
  506.  
  507. Q10: What is a reference?
  508. A: A reference is an alias (an alternate name) for an object.  It is frequently
  509. used for pass-by-reference; ex:
  510.  
  511.     void swap(int& i, int& j)
  512.     {
  513.       int tmp = i;
  514.       i = j;
  515.       j = tmp;
  516.     }
  517.  
  518.     main()
  519.     {
  520.       int x, y;
  521.       //...
  522.       swap(x,y);
  523.     }
  524.  
  525. Here `i' and `j' are aliases for main's `x' and `y' respectively.  The effect
  526. is as if you used the C style pass-by-pointer, but the `&' is moved from the
  527. caller into the callee.  Pascal enthusiasts will recognize this as a VAR param.
  528.  
  529. ==============================================================================
  530.  
  531. Q11: What happens if you assign to a reference?
  532. A: Assigning to a reference changes the referred-to value, thus a ref is an
  533. `Lvalue' (something that can appear on the `L'eft-hand-side of an assignment
  534. statement) for the referred-to value.  This insight can be pushed a bit farther
  535. by allowing references to be *returned*, thus allowing function calls on the
  536. left hand side of an assignment stmt.
  537.  
  538. ==============================================================================
  539.  
  540. Q12: How can you reseat a reference to make it refer to a different object?
  541. A: Unlike a pointer, once a reference is bound to an object, it can NOT be
  542. `reseated' to another object.  The reference itself isn't an object; you can't
  543. separate the reference from the referred-to-object.  Ex: `&ref' is the address
  544. of the referred-to-object, not of the reference itself.
  545.  
  546. ==============================================================================
  547.  
  548. Q13: When should I use references, and when should I use pointers?
  549. A: Old line C programmers sometimes don't like references since the reference
  550. semantics they provide isn't *explicit* in the caller's code.  After a bit of
  551. C++ experience, however, one quickly realizes this `information hiding' is an
  552. asset rather than a liability.  In particular, reuse-centered OOP tends to
  553. migrate the level of abstraction away from the language of the machine toward
  554. the language of the problem.
  555.  
  556. References are usually preferred over ptrs whenever you don't need `reseating'
  557. (see early question on `How can you reseat a reference').  This usually means
  558. that references are most useful in a class' public interface.  References then
  559. typically appear on the skin of an object, and pointers on the inside.
  560.  
  561. The exception to the above is where a function's parameter or return value
  562. needs a `sentinel' reference.  This is usually best done by returning/taking a
  563. pointer, and giving the NULL pointer this special significance (references
  564. should always alias *objects*, not a dereferenced NULL ptr).
  565.  
  566. ==============================================================================
  567.  
  568. Q14: What are inline fns? What are their advantages? How are they declared?
  569. A: An inline function is a function which gets textually inserted by the
  570. compiler, much like a macro.  Like macros, performance is improved by avoiding
  571. the overhead of the call itself, and (especially!) by the compiler being able
  572. to optimize *through* the call (`procedural integration').  Unlike macros,
  573. arguments to inline fns are always evaluated exactly once, so the `call' is
  574. semantically like a regular function call only faster.  Also unlike macros,
  575. argument types are checked and necessary conversions are performed correctly.
  576.  
  577. Beware that overuse of inline functions can cause code bloat, which can in
  578. turn have a negative performance impact in paging environments.
  579.  
  580. They are declared by using the `inline' keyword when the function is defined:
  581.     inline void f(int i, char c) { /*...*/ }   //an inline function
  582. or by including the function definition itself within a class:
  583.     class X {
  584.     public:
  585.       void f(int i, char c) { /*...*/ }   //inline function within a class
  586.     };
  587. or by defining the member function as `inline' outside the class:
  588.     class X {
  589.     public:
  590.       void f(int i, char c);
  591.     };
  592.     //...
  593.     inline void X::f(int i, char c) {/*...*/} //inline fn outside the class
  594.  
  595. Generally speaking, a function cannot be defined as `inline' after it has been
  596. called.  Inline functions should be defined in a header file, with `outlined'
  597. functions appearing in a `.C' file (or .cpp, etc; see question on file naming
  598. conventions).
  599.  
  600. ==============================================================================
  601.  
  602.         ****  PART 04 -- Constructors and destructors  ****
  603.  
  604. ==============================================================================
  605.  
  606. Q15: What is a constructor?  Why would I ever use one?
  607. A: Objects should establish and maintain their own internal coherence.  The
  608. `maintaining' part is done by ensuring self-consistency is restored after any
  609. operation completes (ex: by incrementing the link count after adding a new link
  610. to a linked list).  The part about `establishing coherence' is the job of a
  611. constructor.
  612.  
  613. Constructors are like `init functions'; they build a valid object.  The
  614. constructor turns a pile of incoherent arbitrary bits into a living object.
  615. Minimally it initializes any internally used fields that are needed, but it may
  616. also allocate resources (memory, files, semaphores, sockets, ...).
  617.  
  618. A constructor is like a `factory': it builds objects from dust.
  619.  
  620. `ctor' is a typical abbreviation for constructor.
  621.  
  622. ==============================================================================
  623.  
  624. Q16: How can I make a constructor call another constructor as a primitive?
  625. A: You can't.  Use an `init()' member function instead (often `private:').
  626.  
  627. ==============================================================================
  628.  
  629. Q17: What are destructors really for?  Why would I ever use them?
  630. A: Destructors are used to release any resources allocated by the object's
  631. constructor.  Ex: a Lock class might lock a semaphore, and the destructor will
  632. release that semaphore.  The usual `resource' being acquired in a constructor
  633. (and subsequently released in a destructor) is dynamically allocated memory.
  634.  
  635. `dtor' is a typical abbreviation for destructor
  636.  
  637. ==============================================================================
  638.  
  639.         ****  PART 05 -- Operator overloading  ****
  640.  
  641. ==============================================================================
  642.  
  643. Q18: What is operator overloading?
  644. A: Operator overloading allows the basic C/C++ operators to have user-defined
  645. meanings on user-defined types (classes).  They are syntactic sugar for
  646. equivalent function calls; ex:
  647.  
  648.     class X {
  649.       //...
  650.     public:
  651.       //...
  652.     };
  653.  
  654.     X add(X, X);    //a top-level function that adds two X's
  655.     X mul(X, X);    //a top-level function that multiplies two X's
  656.  
  657.     X f(X a, X b, X c)
  658.     {
  659.       return add(add(mul(a,b), mul(b,c)), mul(c,a));
  660.     }
  661.  
  662. Now merely replace `add' with `operator+' and `mul' with `operator*':
  663.  
  664.     X operator+(X, X);    //a top-level function that adds two X's
  665.     X operator*(X, X);    //a top-level function that multiplies two X's
  666.  
  667.     X f(X a, X b, X c)
  668.     {
  669.       return a*b + b*c + c*a;
  670.     }
  671.  
  672. ==============================================================================
  673.  
  674. Q19: What operators can/cannot be overloaded?
  675. A: Most can be overloaded. The only C operators that can't be are `.' and `?:'
  676. (and `sizeof', which is technically an operator).  C++ adds a few of its own
  677. operators, most of which can be overloaded except `::' and `.*'.
  678.  
  679. Here's an example of the subscript operator (it returns a reference).
  680. First withOUT operator overloading:
  681.     class Vec {
  682.       int data[100];
  683.     public:
  684.       int& elem(unsigned i) { if (i>99) error(); return data[i]; }
  685.     };
  686.  
  687.     main()
  688.     {
  689.       Vec v;
  690.       v.elem(10) = 42;
  691.       v.elem(12) += v.elem(13);
  692.     }
  693.  
  694. Now simply replace `elem' with `operator[]':
  695.     class Vec {
  696.       int data[100];
  697.     public:
  698.       int& operator[](unsigned i) { if (i>99) error(); return data[i]; }
  699.     };   //^^^^^^^^^^--formerly `elem'
  700.  
  701.     main()
  702.     {
  703.       Vec v;
  704.       v[10] = 42;
  705.       v[12] += v[13];
  706.     }
  707.  
  708. ==============================================================================
  709.  
  710. Q20: Can I create a `**' operator for `to-the-power-of' operations?
  711. A: No.
  712.  
  713. The names of, precedence of, associativity of, and arity of operators is fixed
  714. by the language.  There is no `**' operator in C++, so you cannot create one
  715. for a class type.
  716.  
  717. If you doubt the wisdom of this approach, consider the following code:
  718.     x = y ** z;
  719. Looks like your power operator?  Nope.  z may be a ptr, so this is actually:
  720.     x = y * (*z);
  721. Lexical analysis groups characters into tokens at the lowest level of the
  722. compiler's operations, so adding new operators would present an implementation
  723. nightmare (not to mention the increased maintenance cost to read the code!).
  724.  
  725. Besides, operator overloading is just syntactic sugar for function calls.  It
  726. does not add fundamental power to the language (although this particular
  727. syntactic sugar can be very sweet, it is not fundamentally necessary).  I
  728. suggest you overload `pow(base,exponent)', for which a double precision version
  729. is provided by the ANSI-C <math.h> library.
  730.  
  731. By the way: operator^ looks like a good candidate for to-the-power-of, but it
  732. has neither the proper precedence nor associativity.
  733.  
  734. ==============================================================================
  735.  
  736.         ****  PART 06 -- Friends  ****
  737.  
  738. ==============================================================================
  739.  
  740. Q21: What is a `friend'?
  741. A: Friends can be either functions or other classes.  The class grants friends
  742. access privileges.  Normally a developer has political and technical control
  743. over both the class, its members, and its friends (that way you avoid political
  744. problems when you want to update a portion, since you don't have to get
  745. permission from the present owner of the other piece(s)).
  746.  
  747. ==============================================================================
  748.  
  749. Q22: Do `friends' violate encapsulation?
  750. A: Friends can be looked at three ways: (1) they are not class members and they
  751. therefore violate encapsulation of the class members by their mere existence,
  752. (2) a class' friends are absorbed into that class' encapsulation barrier, and
  753. (3) any time anyone wants to do anything tricky they textedit the header file
  754. and add a new friend so they can get right in there and fiddle 'dem bits.
  755.  
  756. No one argues that (3) is a Good Thing, and for good reasons. The arguments for
  757. (1) always boil down to the rather arbitrary and somewhat naive view that a
  758. class' member functions `should' be the *only* functions inside a class'
  759. encapsulation barrier.  I have not seen this view bear fruit by enhancing
  760. software quality.  On the other hand, I have seen (2) bear fruit by lowering
  761. the *overall* coupling in a software system.  Reason: friends can be used as
  762. `liaisons' to provide safe, screened access for the whole world, perhaps in a
  763. way that the class syntactically or semantically isn't able to do for itself.
  764.  
  765. Conclusion: friend functions are merely a syntactic variant of a class' public
  766. access functions.  When used in this manner, they don't violate encapsulation
  767. any more than a member function violates encapsulation.  Thus a class' friends
  768. and members *are* the encapsulation barrier, as defined by the class itself.
  769.  
  770. I've actually seen the `friends always violate encapsulation' view *destroy*
  771. encapsulation: programmers who have been taught that friends are inherently
  772. evil want to avoid them, but they have another class or fn that needs access to
  773. some internal detail in the class, so they provide a member fn which exposes
  774. the class' internal details to the PUBLIC!  Private decisions should stay
  775. private, and only those inside your encapsulation barrier (your members,
  776. friends, and [for `protected' things] your subclasses) should have access.
  777.  
  778. ==============================================================================
  779.  
  780. Q23: What are some advantages/disadvantages of using friends?
  781. A: The advantage of using friends is generally syntactic.  Ie: both a member fn
  782. and a friend are equally privileged (100% vested), but a friend function can be
  783. called like f(obj), where a member is called like obj.f().  When it's not for
  784. syntactic reasons (which is not a `bad' reason -- making an abstraction's
  785. syntax more readable lowers maintenance costs!), friends are used when two or
  786. more classes are designed to be more tightly coupled than you want for `joe
  787. public' (ex: you want to allow class `ListIter' to have more privilege with
  788. class `List' than you want to give to `main()').
  789.  
  790. Friends have three disadvantages.  The first disadvantage is that they add to
  791. the global namespace.  In contrast, the namespace of member functions is buried
  792. within the class, reducing the chance for namespace collisions for functions.
  793.  
  794. The second disadvantage is that they aren't inherited.  That is, the
  795. `friendship privilege' isn't inherited.  This is actually an advantage when it
  796. comes to encapsulation.  Ex: I may declare you as my friend, but that doesn't
  797. mean I trust your kids.
  798.  
  799. The third disadvantage is that they don't bind dynamically.  Ie: they don't
  800. respond to polymorphism.  There are no virtual friends; if you need one, have a
  801. friend call a hidden (usually `protected:') virtual member fn.  Friends that
  802. take a ptr/ref to a class can also take a ptr/ref to a publically derived class
  803. object, so they act as if they are inherited, but the friendship *rights* are
  804. not inherited (the friend of a base has no special access to a class derived
  805. from that base).
  806.  
  807. ==============================================================================
  808.  
  809. Q24: What does it mean that `friendship is neither inherited nor transitive'?
  810. A: This is speaking of the access privileges granted when a class declares a
  811. friend.
  812.  
  813. The access privilege of friendship is not inherited:
  814.  * I may trust you, but I don't necessarily trust your kids.
  815.  * My friends aren't necessarily friends of my kids.
  816.  * Class `Base' declares f() to be a friend, but f() has no special access
  817.    rights with class `Derived'.
  818.  
  819. The access privilege of friendship is not transitive:
  820.  * I may trust you, and you may trust Sam, but that doesn't necessarily mean
  821.    that I trust Sam.
  822.  * A friend of a friend is not necessarily a friend.
  823.  
  824. ==============================================================================
  825.  
  826. Q25: When would I use a member function as opposed to a friend function?
  827. A: Use a member when you can, and a friend when you have to.
  828.  
  829. Like in real life, my family members have certain privileges that my friends do
  830. not have (ex: my family members inherit from me, but my friends do not, etc).
  831. To grant privileged access to a function, you need either a friend or a member;
  832. there is no additional loss of encapsulation one way or the other.  Sometimes
  833. friends are syntactically better (ex: in class `X', friend fns allow the `X'
  834. param to be second, while members require it to be first).  Another good use of
  835. friend functions are the binary infix arithmetic operators.  Ex: `aComplex +
  836. aComplex' probably should be defined as a friend rather than a member, since
  837. you want to allow `aFloat + aComplex' as well (members don't allow promotion of
  838. the left hand arg, since that would change the class of the object that is the
  839. recipient of the message).
  840.  
  841. ==============================================================================
  842.  
  843. --
  844. Marshall Cline
  845. --
  846. Marshall P. Cline, Ph.D. / Paradigm Shift, Inc / One Park St/Norwood, NY 13668
  847. cline@parashift.com / 315-353-6100 / FAX: 315-353-6110
  848.  
  849.  
  850. From charnel!olivea!uunet!gatech!news.ans.net!rpi!clarkson!news.clarkson.edu!cline Sat Jul 10 22:37:08 PDT 1993
  851. Article: 40542 of comp.lang.c++
  852. Newsgroups: comp.lang.c++,news.answers
  853. Path: charnel!olivea!uunet!gatech!news.ans.net!rpi!clarkson!news.clarkson.edu!cline
  854. From: cline@sun.soe.clarkson.edu (Marshall Cline)
  855. Subject: comp.lang.c++ FAQ (posting 2 of 4)
  856. Message-ID: <CLINE.93Jul9063947@cheetah.clarkson.edu>
  857. Sender: news@news.clarkson.edu
  858. Nntp-Posting-Host: cheetah.ece.clarkson.edu
  859. Reply-To: cline@parashift.com (Marshall Cline)
  860. Organization: Paradigm Shift, Inc (Reuse/C++/OOD training, C++ libraries)
  861. Date: Fri, 9 Jul 1993 11:39:47 GMT
  862. Approved: news-answers-request@MIT.Edu
  863. Expires: Mon, 9 Aug 1993 10:33:11 GMT
  864. Lines: 825
  865. Xref: charnel comp.lang.c++:40542 news.answers:10206
  866.  
  867. ==============================================================================
  868.  
  869.     ****  PART 07 -- Input/output via <iostream.h> and <stdio.h>  ****
  870.  
  871. ==============================================================================
  872.  
  873. Q26: How can I provide printing for a `class X'?
  874. A: Provide a friend operator<<:
  875.  
  876.     class X {
  877.     public:
  878.       friend ostream& operator<< (ostream& o, const X& x)
  879.         { return o << x.i; }
  880.       //...
  881.     private:
  882.       int i;    //just for illustration
  883.     };
  884.  
  885. We use a friend rather than a member since the `X' parameter is 2nd, not 1st.
  886. Input is similar, but the signature is:
  887.     istream& operator>> (istream& i, X& x);  //not `const X& x' !!
  888.  
  889. ==============================================================================
  890.  
  891. Q27: Why should I use <iostream.h> instead of the traditional <stdio.h>?
  892. A: See next question.
  893.  
  894. ==============================================================================
  895.  
  896. Q28: Printf/scanf weren't broken; why `fix' them with ugly shift operators?
  897. A: The overloaded shift operator syntax is strange at first sight, but it
  898. quickly grows on you.  However syntax is just syntax; the real issues are
  899. deeper.  Printf is arguably not broken, and scanf is perhaps livable despite
  900. being error prone, however both are limited with respect to what C++ I/O can
  901. do.  C++ I/O (left/right shift) is, relative to C (printf/scanf):
  902.  * type safe -- type of object being I/O'd is known statically by the compiler
  903.     rather than via dynamically tested '%' fields
  904.  * less error prone -- redundant info has greater chance to get things wrong
  905.     C++ I/O has no redundant '%' tokens to get right
  906.  * faster -- printf is basically an `interpreter' of a tiny language whose
  907.     constructs mainly include '%' fields.  the proper low-level routine is
  908.     chosen at runtime based on these fields.  C++ I/O picks these routines
  909.     statically based on actual types of the args
  910.  * extensible -- perhaps most important of all, the C++ I/O mechanism is
  911.     extensible to new user-defined data types (imagine the chaos if
  912.     everyone was simultaneously adding new incompatible '%' fields to
  913.     printf and scanf?!).  Remember: we want to make user-defined types
  914.     (classes) look and act like `built-in' types.
  915.  * subclassable -- ostream and istream (the C++ replacements for FILE*) are
  916.     real classes, and hence subclassable.  This means you can have other
  917.     user defined things that look and act like streams, yet that do
  918.     whatever strange and wonderful things you want.  You automatically
  919.     get to use the zillions of lines of I/O code written by users you
  920.     don't even know, and they don't need to know about your `extended
  921.     stream' class.  Ex: you can have a `stream' that writes to a memory
  922.     area (incore formatting provided by the standard class `strstream'),
  923.     or you could have it use the stdio buffers, or [you name it...].
  924.  
  925. ==============================================================================
  926.  
  927.         ****  PART 08 -- Freestore management  ****
  928.  
  929. ==============================================================================
  930.  
  931. Q29: Does `delete ptr' delete the ptr or the pointed-to-data?
  932. A: The pointed-to-data.
  933.  
  934. When you read `delete p', say to yourself `delete the thing pointed to by p'.
  935. One could argue that the keyword is misleading, but the same abuse of English
  936. occurs when `free'ing the memory pointed to by a ptr in C:
  937.     free(ptr);    /* why not `free_the_stuff_pointed_to_by(p)' ?? */
  938.  
  939. ==============================================================================
  940.  
  941. Q30: Can I free() ptrs alloc'd with `new' or `delete' ptrs alloc'd w/ malloc()?
  942. A: No.  You should not mix C and C++ heap management.
  943.  
  944. ==============================================================================
  945.  
  946. Q31: Why should I use `new' instead of trustworthy old malloc()?
  947. A: malloc() doesn't call constructors, and free() doesn't call destructors.
  948. Besides, malloc() isn't type safe, since it returns a `void*' rather than a ptr
  949. of the right type (ANSI-C punches a hole in its typing system to make it
  950. possible to use malloc() without pointer casting the return value, but C++
  951. closes that hole).  Besides, `new' is an operator that can be overridden by a
  952. class, while `malloc' is not overridable on a per-class basis (ie: even if the
  953. class doesn't have a constructor, allocating via malloc might do inappropriate
  954. things if the freestore operations have been overridden).
  955.  
  956. ==============================================================================
  957.  
  958. Q32: Why doesn't C++ have a `realloc()' along with `new' and `delete'?
  959. A: Because realloc() does *bitwise* copies (when it has to copy), which will
  960. tear most C++ objects to shreds.  C++ objects know how to copy themselves.
  961. They use their own copy constructor or assignment operator (depending on
  962. whether we're copying into a previously unused space [copy-ctor] or a previous
  963. object [assignment op]).
  964.  
  965. Moral: never use realloc() on objects of a class.  Let the class copy its own
  966. objects.
  967.  
  968. ==============================================================================
  969.  
  970. Q33: How do I allocate / unallocate an array of things?
  971. A: Use new[] and delete[]:
  972.  
  973.     Thing* p = new Thing[100];
  974.     //...
  975.     delete [] p;    //older compilers require you to use `delete [100] p'
  976.  
  977. Any time you allocate an array of things (ie: any time you use the `[...]' in
  978. the `new' expression) you *!*MUST*!* use the `[]' in the `delete' statement.
  979.  
  980. The fact that there is no syntactic difference between a ptr to a thing and a
  981. ptr to an array of things is an artifact we inherited from C.
  982.  
  983. ==============================================================================
  984.  
  985. Q34: What if I forget the `[]' when `delete'ing array allocated via `new X[n]'?
  986. A: Life as we know it suddenly comes to a catastrophic end.
  987.  
  988. It is the programmer's --not the compiler's-- responsibility to get the
  989. connection between new[] and delete[] correct.  If you get it wrong, neither a
  990. compile-time nor a run-time error message will be generated by the compiler.
  991.  
  992. Heap corruption is a likely result.
  993.  
  994. ==============================================================================
  995.  
  996.         ****  PART 09 -- Debugging and error handling  ****
  997.  
  998. ==============================================================================
  999.  
  1000. Q35: How can I handle a constructor that fails?
  1001. A: Constructors (ctors) do not return any values, so no returned error code
  1002. is possible.  The best way to handle failure is therefore to `throw' an
  1003. exception.
  1004.  
  1005. If your compiler doesn't yet support exceptions, several possibilities remain.
  1006. The simplest is to put the object itself into a `half baked' state by setting
  1007. an internal status bit.  Naturally there should be a query (`inspector') method
  1008. to check this bit, allowing clients to discover whether they have a live
  1009. object.  Other member functions should check this bit, and either do a no-op
  1010. (or perhaps something more obnoxious such as `abort()') if the object isn't
  1011. really alive.  Check out how the iostreams package handles attempts to open
  1012. nonexistent/illegal files for an example of prior art.
  1013.  
  1014. ==============================================================================
  1015.  
  1016. Q36: How can I compile-out my debugging print statements?
  1017. A: This will NOT work, since comments are parsed before the macro is expanded:
  1018.     #ifdef DEBUG_ON
  1019.       #define  DBG
  1020.     #else
  1021.       #define  DBG  //
  1022.     #endif
  1023.     DBG cout << foo;
  1024.  
  1025. This is the simplest technique:
  1026.     #ifdef DEBUG_ON
  1027.       #define  DBG(anything)  anything
  1028.     #else
  1029.       #define  DBG(anything)  /*nothing*/
  1030.     #endif
  1031.  
  1032. Then you can say:
  1033.     //...
  1034.     DBG(cout << "the value of foo is " << foo << '\n');
  1035.     //                                                ^-- `;' outside ()
  1036.  
  1037. Any commas in your `DBG()' statement must be enclosed in a `()':
  1038.     DBG(i=3, j=4);    //<---- C-preprocessor will generate error message
  1039.     DBG(i=3; j=4);    //<---- ok
  1040.  
  1041. There are also more complicated techniques that use variable argument lists,
  1042. but these are primarily useful for `printf()' style (see question on the pros
  1043. and cons of <iostream.h> as opposed to <stdio.h> for more).
  1044.  
  1045. ==============================================================================
  1046.  
  1047.         ****  PART 10 -- Const correctness  ****
  1048.  
  1049. ==============================================================================
  1050.  
  1051. Q37: What is `const correctness'?
  1052. A: A program is `const correct' if it never mutates a constant object.  This is
  1053. achieved by using the keyword `const'.  Ex: if you pass a String to a function
  1054. `f()', and you wish to prohibit `f()' from modifying the original String, you
  1055. can either pass by value:    void  f(      String  s   )  { /*...*/ }
  1056. or by constant reference:    void  f(const String& s   )  { /*...*/ }
  1057. or by constant pointer:        void  f(const String* sptr)  { /*...*/ }
  1058. but *not* by non-const ref:    void  f(      String& s   )  { /*...*/ }
  1059. *nor* by non-const pointer:    void  f(      String* sptr)  { /*...*/ }
  1060.  
  1061. Attempted changes to `s' within a fn that takes a `const String&' are flagged
  1062. as compile-time errors; neither run-time space nor speed is degraded.
  1063.  
  1064. ==============================================================================
  1065.  
  1066. Q38: Is `const correctness' a good goal?
  1067. A: Declaring the `constness' of a parameter is just another form of type
  1068. safety.  It is almost as if a constant String, for example, `lost' its various
  1069. mutative operations.  If you find type safety helps you get systems correct
  1070. (especially large systems), you'll find const correctness helps also.
  1071.  
  1072. Short answer: yes, const correctness is a good goal.
  1073.  
  1074. ==============================================================================
  1075.  
  1076. Q39: Is `const correctness' tedious?
  1077. A: Type safety requires you to annotate your code with type information.  In
  1078. theory, expressing this type information isn't necessary -- witness untyped
  1079. languages as an example of this.  However in practice, programmers often know
  1080. in their heads a lot of interesting information about their code, so type
  1081. safety (and, by extension, const correctness) merely provide structured ways to
  1082. get this information into their keyboards.
  1083.  
  1084. Short answer: yes, const correctness is tedious.
  1085.  
  1086. ==============================================================================
  1087.  
  1088. Q40: Should I try to get things const correct `sooner' or `later'?
  1089. A: Back-patching const correctness is *very* expensive.  Every `const' you add
  1090. `over here' requires you to add four more `over there'.  The snowball effect is
  1091. magnificent -- unless you have to pay for it.  Long about the middle of the
  1092. process, someone stumbles on a function that needs to be const but can't be
  1093. const, and then they know why their system wasn't functioning correctly all
  1094. along.  This is the benefit of const correctness, but it should be installed
  1095. from the beginning.
  1096.  
  1097. Short answer: CONST CORRECTNESS SHOULD NOT BE DONE RETROACTIVELY!!
  1098.  
  1099. ==============================================================================
  1100.  
  1101. Q41: What is a `const member function'?
  1102. A: A const member function is a promise to the caller not to change the object.
  1103. Put the word `const' after the member function's signature; ex:
  1104.     class X {
  1105.       //...
  1106.       void f() const;
  1107.     };
  1108.  
  1109. Some programmers feel this should be a signal to the compiler that the raw bits
  1110. of the object's `struct' aren't going to change, others feel it means the
  1111. *abstract* (client-visible) state of the object isn't going to change.  C++
  1112. compilers aren't allowed to assume the bitwise const, since a non-const alias
  1113. could exist which could modify the state of the object (gluing a `const' ptr to
  1114. an object doesn't promise the object won't change; it only promises that the
  1115. object won't change **via that pointer**).
  1116.  
  1117. I talked to Jonathan Shopiro at the C++AtWork conference, and he confirmed that
  1118. the above view has been ratified by the ANSI-C++ standards board.  This doesn't
  1119. make it a `perfect' view, but it will make it `the standard' view.
  1120.  
  1121. See the next few questions for more.
  1122.  
  1123. ==============================================================================
  1124.  
  1125. Q42: What is an `inspector'?  What is a `mutator'?
  1126. A: An inspector inspects and a mutator mutates.  These different categories of
  1127. member fns are distinguished by whether the member fn is `const' or not.
  1128.  
  1129. ==============================================================================
  1130.  
  1131. Q43: What is `casting away const in an inspector' and why is it legal?
  1132. A: In current C++, const member fns are allowed to `cast away the const-ness of
  1133. the "this" ptr'.  Programmers use (some say `misuse') this to tickle internally
  1134. used counters, cache values, or some other non-client-visible change.  Since
  1135. C++ allows you to use const member fns to indicate the abstract/meaning-wise
  1136. state of the object doesn't change (as opposed to the concrete/bit-wise state),
  1137. the `meaning' of the object shouldn't change during a const member fn.
  1138.  
  1139. Those who believe `const' member fns shouldn't be allowed to change the bits of
  1140. the struct itself call the `abstract const' view `Humpty Dumpty const' (Humpty
  1141. Dumpty said that words mean what he wants them to mean).  The response is that
  1142. a class' public interface *should* mean exactly what the class designer wants
  1143. it to mean, in Humpty Dumpty's words, `nothing more and nothing less'.  If the
  1144. class designer says that accessing the length of a List doesn't change the
  1145. List, then one can access the length of a `const' List (even though the `len()'
  1146. member fn may internally cache the length for future accesses).
  1147.  
  1148. Some proposals are before the ANSI/ISO C++ standards bodies to provide syntax
  1149. that allows individual data members to be designated as `can be modified in a
  1150. const member fn' using a prefix such as `~const'.  This would blend the best of
  1151. the `give the compiler a chance to cache data across a const member fn', but
  1152. only if aliasing can be solved (see next question).
  1153.  
  1154. ==============================================================================
  1155.  
  1156. Q44: But doesn't `cast away const' mean lost optimization opportunities?
  1157. A: If the object is constructed in the scope of the const member fn invocation,
  1158. and if all the non-const member function invocations between the object's
  1159. construction and the const member fn invocation are statically bound, and if
  1160. every one of these invocations is also `inline'd, and if the ctor itself is
  1161. `inline', and if any member fns the ctor calls are inline, then the answer is
  1162. `Yes, the soon-to-be-standard interpretation of the language would prohibit a
  1163. very smart compiler from detecting the above scenario, and the register cache
  1164. would be unnecessarily flushed'.  The reader should judge whether the above
  1165. scenario is common enough to warrant a language change which would break
  1166. existing code.
  1167.  
  1168. ==============================================================================
  1169.  
  1170.         ****  PART 11 -- Inheritance  ****
  1171.  
  1172. ==============================================================================
  1173.  
  1174. Q45: What is inheritance?
  1175. A: Inheritance is what separates abstract data type (ADT) programming from OOP.
  1176. It is not a `dark corner' of C++ by any means.  In fact, everything discussed
  1177. so far could be simulated in your garden variety ADT programming language (ex:
  1178. Ada, Modula-2, C [with a little work], etc).  Inheritance and the consequent
  1179. (subclass) polymorphism are the two big additions which separate a language
  1180. like Ada from an object-oriented programming language.
  1181.  
  1182. ==============================================================================
  1183.  
  1184. Q46: Ok, ok, but what is inheritance?
  1185. A: Human beings abstract things on two dimensions: part-of and kind-of.  We say
  1186. that a Ford Taurus is-a-kind-of-a Car, and that a Ford Taurus has parts such as
  1187. Engine, Tire, etc.  The part-of hierarchy has been a first class part of
  1188. software since the ADT style became relevant, but programmers have had to whip
  1189. up their own customized techniques for simulating kind-of (usually in an ad hoc
  1190. manner).  Inheritance changes that; it adds `the other' major dimension of
  1191. decomposition.
  1192.  
  1193. An example of `kind-of decomposition', consider the genus/species biology
  1194. charts.  Knowing the internal parts of various fauna and flora is important for
  1195. certain applications, but knowing the groupings (kinds, categories) is equally
  1196. important.
  1197.  
  1198. ==============================================================================
  1199.  
  1200. Q47: How do you express inheritance in C++?
  1201. A: By the `: public' syntax:
  1202.  
  1203.     class Car : public Vehicle {
  1204.             //^^^^^^^^---- `: public' is pronounced `is-a-kind-of-a'
  1205.       //...
  1206.     };
  1207.  
  1208. We state the above relationship in several ways:
  1209.  * Car is `a kind of a' Vehicle
  1210.  * Car is `derived from' Vehicle
  1211.  * Car is `a specialized' Vehicle
  1212.  * Car is the `subclass' of Vehicle
  1213.  * Vehicle is the `base class' of Car
  1214.  * Vehicle is the `superclass' of Car (this not as common in the C++ community)
  1215.  
  1216. ==============================================================================
  1217.  
  1218. Q48: What is `incremental programming'?
  1219. A: In addition to being an abstraction mechanism that makes is-a-kind-of
  1220. relationships explicit, inheritance can also be used as a means of `incremental
  1221. programming'.  A derived class inherits all the representation (bits) of its
  1222. base class, plus all the base class' mechanism (code).  Another device (virtual
  1223. functions, described below) allows derived classes to selectively override some
  1224. or all of the base class' mechanism (replace and/or enhance the various
  1225. algorithms).
  1226.  
  1227. This simple ability is surprisingly powerful: it effectively adds a `third
  1228. dimension' to programming.  After becoming fluent in C++, most programmers find
  1229. languages like C and Ada to be `flat' (a cute little book, `Flatland', aptly
  1230. describes those living in a two dimensional plane, and their disbelief about a
  1231. strange third dimension that is somehow neither North, South, East nor West,
  1232. but is `Up').
  1233.  
  1234. As a trivial example, suppose you have a Linked List that is too slow, and you
  1235. wish to cache its length.  You could `open up' the List `class' (or `module'),
  1236. and modify it directly (which would certainly be appropriate for such a simple
  1237. situation), but suppose the List's physical size is critical, and some
  1238. important client cannot afford to add the extra machine word to every List.
  1239. Another option would be to textually copy the List module and modify the copy,
  1240. but this increases the amount of code that must be maintained, and also
  1241. presumes you have access to the internal source code of the List module.  The
  1242. OO solution is to realize that a List that caches its length is-a-kind-of-a
  1243. List, so we inherit:
  1244.  
  1245.     class FastList : public List {
  1246.     public:
  1247.       //override operations so the cache stays `hot'
  1248.     protected:
  1249.       int length;    //cache the length here
  1250.     };
  1251.  
  1252. ==============================================================================
  1253.  
  1254. Q49: Should I pointer-cast from a derived class to its base class?
  1255. A: The short answer: yes -- you don't even need the `cast'.
  1256.  
  1257. Long answer: a derived class is a specialized version of the base class
  1258. (`Derived is-a-kind-of-a Base').  The upward conversion is perfectly safe, and
  1259. happens all the time (a ptr to a Derived is in fact pointing to a [specialized
  1260. version of a] Base):
  1261.     void f(Base* base_ptr);
  1262.     void g(Derived* derived_ptr) { f(derived_ptr); }  //perfectly safe; no cast
  1263.  
  1264. (note that the answer to this question assumes we're talking about `public'
  1265. derivation; see below on `private/protected' inheritance for `the other kind').
  1266.  
  1267. ==============================================================================
  1268.  
  1269. Q50: Derived* --> Base* works ok; why doesn't Derived** --> Base** work?
  1270. A: A C++ compiler will allow a Derived* to masquerade as a Base*, since a
  1271. Derived object is a kind of a Base object.  However passing a Derived** as a
  1272. Base** (or otherwise trying to convert a Derived** to a Base**) is (correctly)
  1273. flagged as an error.
  1274.  
  1275. An array of Deriveds is-NOT-a-kind-of-an array of Bases.  I like to use the
  1276. following example in my C++ training sessions:
  1277.         `A Bag of Apples is *NOT* a Bag of Fruit'
  1278.  
  1279. Suppose a `Bag<Apple>' could be passed to a function taking a Bag<Fruit> such
  1280. as `f(Bag<Fruit>& b)'.  But `f()' can insert *any* kind of Fruit into the Bag.
  1281. Imagine the surprise on the caller's face when he gets the Bag back only to
  1282. find it has a Banana in it!
  1283.  
  1284. Here's another example I use:
  1285.     A ParkingLot of Car is-NOT-a-kind-of-a ParkingLot of Vehicle
  1286. (otherwise you could pass a ParkingLot<Car>* as a ParkingLot<Vehicle>*, and the
  1287. called fn could park an EighteenWheeler in a ParkingLot designed for Cars!)
  1288.  
  1289. These improper things are violations of `contravariance' (that's the scientific
  1290. glue that holds OOP together).  C++ enforces contravariance, so you should
  1291. trust your compiler at moments like these.  Contravariance is more solid than
  1292. our fickle intuition.
  1293.  
  1294. ==============================================================================
  1295.  
  1296. Q51: Does array-of-Derived is-NOT-a-kind-of array-of-Base mean arrays are bad?
  1297. A: Yes, `arrays are evil' (jest kidd'n :-).
  1298.  
  1299. There's a very subtle problem with using raw built-in arrays.  Consider this:
  1300.  
  1301.     void f(Base* array_of_Base)
  1302.     {
  1303.       array_of_Base[3].memberfn();
  1304.     }
  1305.  
  1306.     main()
  1307.     {
  1308.       Derived array_of_Derived[10];
  1309.       f(array_of_Derived);
  1310.     }
  1311.  
  1312. This is perfectly type-safe, since a D* is-a B*, but it is horrendously evil,
  1313. since Derived might be larger than Base, so the array index in f() not only
  1314. isn't type safe, it's not even going to be pointing at a real object!  In
  1315. general it'll be pointing somewhere into the innards of some poor D.
  1316.  
  1317. The fundamental problem here is that C++ cannot distinguish a ptr-to-a-thing
  1318. from a ptr-to-an-array-of-things (witness the required `[]' in `delete[]' when
  1319. deleting an array as another example of how these different kinds of ptrs are
  1320. actually different).  Naturally C++ `inherited' this feature from C.
  1321.  
  1322. This underscores the advantage of using an array-like *class* instead of using
  1323. a raw array (the above problem would have been properly trapped as an error if
  1324. we had used a `Vec<T>' rather than a `T[]'; ex: you cannot pass a Vec<Derived>
  1325. to `f(Vec<Base>& v)').
  1326.  
  1327. ==============================================================================
  1328. SUBSECTION: Inheritance -- virtual functions
  1329. ==============================================================================
  1330.  
  1331. Q52: What is a `virtual member function'?
  1332. A: A virtual member function is a member fn preceded by the keyword `virtual'.
  1333.  
  1334. It has the effect of allowing derived classes to replace the implementation of
  1335. the fn.  Furthermore the replacement is always called whenever the object in
  1336. question is actually of the derived class.  The impact is that algorithms in
  1337. the base class can be replaced in the derived class without affecting the
  1338. operation of the base class.  The replacement can be either full or partial,
  1339. since the derived class operation can invoke the base class version if desired.
  1340.  
  1341. This is discussed further below.
  1342.  
  1343. ==============================================================================
  1344.  
  1345. Q53: What is dynamic dispatch?  Static dispatch?
  1346. A: In the following discussion, `ptr' means either a pointer or a reference.
  1347.  
  1348. When you have a ptr to an object, there are two distinct types in question: the
  1349. static type of the ptr, and the dynamic type of the pointed-to object (the
  1350. object may actually be of a class that is derived from the class of the ptr).
  1351.  
  1352. The `legality' of the call is checked based on the static type of the ptr,
  1353. which gives us static type safety (if the type of the ptr can handle the member
  1354. fn, certainly the pointed-to object can handle it as well, since the pointed-to
  1355. object is of a class that is derived from the ptr's class).
  1356.  
  1357. Suppose ptr's type is `List' and the pointed-to object's type is `FastList'.
  1358. Suppose the fn `len()' is provided in `List' and overridden in `FastList'.  The
  1359. question is: which function should actually be invoked: the function attached
  1360. to the pointer's type (`List::len()') or the function attached to the object
  1361. itself (`FastList::len()')?
  1362.  
  1363. If `len()' is a virtual function, as it would be in the above case, the fn
  1364. attached to the object is invoked.  This is called `dynamic binding', since the
  1365. actual code being called is determined dynamically (at run time).
  1366.  
  1367. On the other hand, if `len()' were non-virtual, the dispatch would be resolved
  1368. statically to the fn attached to the ptr's class.
  1369.  
  1370. ==============================================================================
  1371.  
  1372. Q54: Can I override a non-virtual fn?
  1373. A: Yes but you shouldn't.  The only time you should do this is to get around
  1374. the `hiding rule' (see below, and ARM sect.13.1), and the overridden definition
  1375. should be textually identical to the base class' version.
  1376.  
  1377. The above advice will keep you out of trouble, but it is a bit too strong.
  1378. Experienced C++ programmers will sometimes override a non-virtual fn for
  1379. efficiency, and will provide an alternate implementation which makes better use
  1380. of the derived class' resources.  However the client-visible effects must be
  1381. *identical*, since non-virtual fns are dispatched based on the static type of
  1382. the ptr/ref rather than the dynamic type of the pointed-to/referenced object.
  1383.  
  1384. ==============================================================================
  1385.  
  1386. Q55: Why do I get the warning "Derived::foo(int) hides Base::foo(double)"?
  1387. A: A member function in a derived class will *hide* all member functions of the
  1388. same name in the base class, *not* overload them, even if Base::foo(double) is
  1389. virtual (see ARM 13.1).  This is done because it was felt that programmers
  1390. would, for example, call a_derived.foo(1) and expect Derived::foo(double) to be
  1391. called.  If you define any member function with the name `foo' in a derived
  1392. class, you must redefine in class Derived all other Base::foo()'s that you wish
  1393. to allow access from a Derived object (which generally means all of them; you
  1394. should [generally] *not* try to hide inherited public member functions since it
  1395. breaks the `conformance' of the derived class with respect to the base class).
  1396.  
  1397.    class Base {
  1398.    public:
  1399.      void foo(int);
  1400.    };
  1401.  
  1402.    class Derived : public Base {
  1403.    public:
  1404.      void foo(double);
  1405.      void foo(int i) { Base::foo(i); }    // <-- override it with itself
  1406.    };
  1407.  
  1408. ==============================================================================
  1409. SUBSECTION: Inheritance -- conformance
  1410. ==============================================================================
  1411.  
  1412. Q56: Can I `revoke' or `hide' public member fns inherited from my base class?
  1413. A: Never never never do this.  Never.  NEVER!
  1414.  
  1415. This is an all-too-common design error.  It usually stems from muddy thinking
  1416. (but sometimes it stems from a very difficult design that doesn't seem to yield
  1417. anything elegant).
  1418.  
  1419. ==============================================================================
  1420.  
  1421. Q57: Is a `Circle' a kind-of an `Ellipse'?
  1422. A: Depends on what you claim an Ellipse can do.  Ex: suppose Ellipse has a
  1423. `scale(x,y)' method, which is meaningless for Circle.
  1424.  
  1425. There are no easy options at this point, but the worst of all possible worlds
  1426. is to keep muddling along and hope that no one stubs their toes over the bad
  1427. design (if we're serious about reuse, we should fix our mistakes rather than
  1428. leave them to a future generation).  If an Ellipse can do something a Circle
  1429. can't, a Circle can't be a kind of Ellipse.  Should there be any other
  1430. relationship between Circle and Ellipse?  Here are two reasonable options:
  1431.  * make Circle and Ellipse completely unrelated classes.
  1432.  * derive Circle and Ellipse from a base class representing `Ellipses that
  1433.    can't *necessarily* perform an unequal-scale operation'.
  1434.  
  1435. In the first case, Ellipse could be derived from class `AsymmetricShape' (with
  1436. scale(x,y) being introduced in AsymmetricShape), and Circle should be derived
  1437. from `SymmetricShape', which has a scale(factor) member fn.
  1438.  
  1439. In the second case, we could create class `Oval' that has only an equal scale
  1440. operation, then derive both `Ellipse' and `Circle' from Oval, where Ellipse
  1441. --but not Circle-- adds the unequal scale operation (see the `hiding rule' for
  1442. a caveat if the same method name `scale' is used for both unequal and equal
  1443. scale operations).
  1444.  
  1445. In any event, we could create an operation to create an Ellipse whose size et
  1446. al are the same as a given Circle, but this would be a constructive operation
  1447. (ie: it would create a brand new object, like converting an int to a float, but
  1448. unlike passing a reference to a Circle as if it were a ref to an Ellipse).
  1449.  
  1450. Example:    class Ellipse : public Oval {
  1451.         public:       ^^^^^^^^^^^^^---- or whatever
  1452.           Ellipse(const Circle& circle);
  1453.           //...
  1454.         };
  1455.  
  1456. Or:        class Circle /*...*/ {
  1457.         public:
  1458.           operator Ellipse() const;
  1459.           //...
  1460.         };
  1461.  
  1462. ==============================================================================
  1463.  
  1464. Q58: Are there other options to the `Circle is/isnot kind-of Ellipse' dilemma?
  1465. A: There appear to be 2 other options (but read below for why these are poor):
  1466.  * redefine Circle::scale(x,y) to throw an exception or call `abort()'.
  1467.  * redefine Circle::scale(x,y) to be a no-op, or to scale both dimensions by
  1468.    the average of the parameters (or some other arbitrary value).
  1469.  
  1470. Throwing an exception will `surprise' clients.  You claimed that a Circle was
  1471. actually a kind of an Ellipse, so they pass a Circle off to `f(Ellipse& e)'.
  1472. The author of this function read the contract for Ellipse very carefully, and
  1473. scale(x,y) is definitely allowed.  Yet when f() innocently calls e.scale(5,3),
  1474. it kills him!  Conclusion: you lied; what you gave them was distinctly *not* an
  1475. Ellipse.
  1476.  
  1477. In the second case, you'll find it to be very difficult to write a meaningful
  1478. semantic specification (a `contract') for Ellipse::scale(x,y).  You'd like to
  1479. be able to say it scales the x-axis by `x' and the y-axis by `y', but the best
  1480. you can say is `it may do what you expect, or it may do nothing, or it may
  1481. scale both x and y even if you asked it to only scale the x (ex: `scale(2,1)').
  1482. Since you've diluted the contract into dribble, the client can't rely on any
  1483. meaningful behavior, so the whole hierarchy begins to be worthless (it's hard
  1484. to convince someone to use an object if you have to shrug your shoulders when
  1485. asked what the object does for them).
  1486.  
  1487. ==============================================================================
  1488. SUBSECTION: Inheritance -- access rules
  1489. ==============================================================================
  1490.  
  1491. Q59: Why can't I access `private' things in a base class from a derived class?
  1492. A: Derived classes do not get access to private members of a base class.  This
  1493. effectively `seals off' the derived class from any changes made to the private
  1494. members of the base class.
  1495.  
  1496. ==============================================================================
  1497.  
  1498. Q60: What's the difference between `public:', `private:', and `protected:'?
  1499. A: `Private' is discussed in the previous section, and `public' means `anyone
  1500. can access it'.  The third option, `protected', makes a member (either data
  1501. member or member fn) accessible to subclasses.
  1502.  
  1503. Thus members defined in the `private:' section of class X are accessible only
  1504. to the member functions and friends of class X; members defined in the
  1505. `public:' section are accessible by everyone; `protected:' members are
  1506. accessible by members fns and friends of class X, as well as member fns of
  1507. subclasses of X.
  1508.  
  1509. ==============================================================================
  1510.  
  1511. Q61: How can I protect subclasses from breaking when I change internal parts?
  1512. A: You can make your software more resilient to internal changes by realizing
  1513. a class has two distinct interfaces for two distinct sets of clients:
  1514.  * its `public:' interface serves unrelated classes
  1515.  * its `protected:' interface serves derived classes
  1516.  
  1517. A class that is intended to have a long and happy life can hide its physical
  1518. bits in its `private:' part, then put `protected:' inline access functions to
  1519. these data.  The private bits can change, but if the protected access fns are
  1520. stable, subclasses (ie: derived classes) won't break (though they'll need to
  1521. be recompiled after a change to the base class).
  1522.  
  1523. ==============================================================================
  1524. SUBSECTION: Inheritance -- constructors and destructors
  1525. ==============================================================================
  1526.  
  1527. Q62: Why does base ctor get *base*'s virtual fn instead of the derived version?
  1528.  
  1529. Ie: when constructing an obj of class `Derived', Base::Base() invokes `virt()'.
  1530. `Derived::virt()' exists (an override of `Base::virt()'), yet `Base::virt()'
  1531. gets control rather than the `Derived' version; why?
  1532.  
  1533. A: A constructor turns raw bits into a living object.  Until the ctor has
  1534. finished, you don't have a complete `object'.  In particular, while the base
  1535. class' ctor is working, the object isn't yet a Derived class object, so the
  1536. call of the base class' virtual fn defn is correct.
  1537.  
  1538. Similarly dtors turn a living object into raw bits (they `blow it to bits'), so
  1539. the object is no longer a Derived during Base's dtor.  Therefore the same thing
  1540. happens: when Base::~Base() calls `virt()', Base::virt() gets control, not the
  1541. Derived::virt() override.  (Think of what would happen if the Derived fn
  1542. touched a subobject from the Derived class, and you'll quickly see the wisdom
  1543. of the approach).
  1544.  
  1545. ==============================================================================
  1546.  
  1547. Q63: Does a derived class dtor need to explicitly call the base destructor?
  1548. A: No, you never need to explicitly call a dtor (where `never' means `rarely').
  1549. ie: you only have to have an explicit dtor call in rather esoteric situations
  1550. such as destroying an object created by the `placement new operator'.  In the
  1551. usual case, a derived class' dtor (whether you explicitly define one or not)
  1552. automatically invokes the dtors for subobjects and base class(es).  Subobjects
  1553. are destroyed immediately after the derived class' destructor body (`{...}'),
  1554. and base classes are destroyed immediately after subobjects.  Subobjects are
  1555. destroyed from bottom to top in the lexical order they appear within a class,
  1556. and base classes from right to left in the order of the base-class-list.
  1557.  
  1558. ==============================================================================
  1559. SUBSECTION: Inheritance -- private and protected inheritance
  1560. ==============================================================================
  1561.  
  1562. Q64: How do you express `private inheritance'?
  1563. A: When you use `: private' instead of `: public'.  Ex:
  1564.  
  1565.     class Foo : private Bar {
  1566.       //...
  1567.     };
  1568.  
  1569. ==============================================================================
  1570.  
  1571. Q65: How are `private derivation' and `containment' similar? dissimilar?
  1572. A: Private derivation can be thought of as a syntactic variant of containment
  1573. (has-a).  Ex: it is NOT true that a privately derived is-a-kind-of-a Base:
  1574.  
  1575. With private derivation:
  1576.     class Car : private Engine {/*...*/};    //a Car is NOT a-kind-of Engine
  1577. Similarly:
  1578.     class Car { Engine e; /*...*/ };    //normal containment
  1579.  
  1580. There are several similarities between these two forms of containment:
  1581.  * in both cases there is exactly one Engine subobject contained in a Car
  1582.  * in neither case can clients (outsiders) convert a Car* to an Engine*
  1583.  
  1584. There are also several distinctions:
  1585.  * the second form is needed if you want to contain several subobjects
  1586.  * the first form can introduce unnecessary multiple inheritance
  1587.  * the first form allows members of Car to convert a Car* to an Engine*
  1588.  * the first form allows access to the `protected' members of the base class
  1589.  * the first form allows Car to override Engine's virtual functions.
  1590.  
  1591. Private inheritance is almost always used for the last item: to gain access
  1592. into the `protected:' members of the base class.
  1593.  
  1594. ==============================================================================
  1595.  
  1596. Q66: Should I pointer-cast from a `privately' derived class to its base class?
  1597. A: The short answer: no, but yes too (better read the long answer!)
  1598.  
  1599. >From `inside' the privately derived class (ie: in the body of members or
  1600. friends of the privately derived class), the relationship to the base class is
  1601. known, and the upward conversion from PrivatelyDer* to Base* (or PrivatelyDer&
  1602. to Base&) is safe and doesn't need a cast.
  1603.  
  1604. >From `outside' the privately derived class, the relationship to `Base' is a
  1605. `private' decision of `PrivatelyDer', so the conversion requires a cast.
  1606. Clients should not exercise this cast, since private derivation is a private
  1607. implementation decision of the privately derived class, and the coercion will
  1608. fail after the privately derived class privately chooses to change this private
  1609. implementation decision.
  1610.  
  1611. Bottom line: only a class and its friends have the right to convert a ptr to a
  1612. derived class into a ptr to its private base class.  They don't need a cast,
  1613. since the relationship with the base class is accessible to them.  No one else
  1614. can convert such ptrs without pointer-casts, so no one else should.
  1615.  
  1616. ==============================================================================
  1617.  
  1618. Q67: Should I pointer-cast from a `protected' derived class to its base class?
  1619. A: Protected inheritance is similar to private inheritance; the answer is `no'.
  1620.     class Car : protected Engine {/*...*/};   //protected inheritance
  1621.  
  1622. In `private' inheritance, only the class itself (and its friends) can know
  1623. about the relation to the base class (the relationship to the base class is a
  1624. `private' decision).  In protected inheritance, the relationship with the base
  1625. class is a `protected' decision, so *subclasses* of the `protectedly' derived
  1626. class can also know about and exploit this relationship.
  1627.  
  1628. This is a `for better *and* for worse' situation: future changes to `protected'
  1629. decisions have further consequences than changing a private decision (in this
  1630. case, the class, its friends, *and* subclasses, sub- sub- classes, etc, all
  1631. need to be examined for dependencies upon the relationship to the base class).
  1632. However it is also for better, in that subclasses have the ability to exploit
  1633. the relationship.
  1634.  
  1635. The existence of protected inheritance in C++ is debated in some circles.
  1636.  
  1637. ==============================================================================
  1638.  
  1639. Q68: What are the access rules with `private' and `protected' inheritance?
  1640. A: Take these classes as examples:
  1641.     class B { /*...*/ };
  1642.     class D_priv : private   B { /*...*/ };
  1643.     class D_prot : protected B { /*...*/ };
  1644.     class D_publ : public    B { /*...*/ };
  1645.     class Client { B b; /*...*/ };
  1646.  
  1647. Public and protected parts of B are `private' in D_priv, and are `protected' in
  1648. D_prot.  In D_publ, public parts of B are public (D_prot is-a-kind-of-a B), and
  1649. protected parts of B remain protected in D_publ.  Naturally *none* of the
  1650. subclasses can access anything that is private in B.  Class `Client' can't
  1651. even access the protected parts of B (ie: it's `sealed off').
  1652.  
  1653. It is often the case that you want to make some but not all inherited member
  1654. functions public in privately/protectedly derived classes.  Ex: to make member
  1655. fn B::f(int,char,float) public in D_prot, you would say:
  1656.     class D_prot : protected B {
  1657.       //...
  1658.     public:
  1659.       B::f;    //note: not  B::f(int,char,float)
  1660.     };
  1661.  
  1662. There are limitations to this technique (can't distinguish overloaded names,
  1663. and you can't make a feature that was `protected' in the base `public' in the
  1664. derived).  Where necessary, you can get around these by a call-through fn:
  1665.     class D_prot : protected B {
  1666.     public:
  1667.       short f(int i, char c, float f) { return B::f(i,c,f); }
  1668.     };
  1669.  
  1670. ==============================================================================
  1671.  
  1672. Q69: Do most C++ programmers use containment or private inheritance?
  1673. A: Short answer: generalizations are always wrong (that's a generalization :-).
  1674.  
  1675. The long answer is another generalization: most C++ programmers use regular
  1676. containment (also called `composition' or `aggregation') more often than
  1677. private inheritance.  The usual reason is that they don't *want* to have access
  1678. to the internals of too many other classes.
  1679.  
  1680. Private inheritance is not evil; it's just more expensive to maintain, since it
  1681. increases the number of classes that have access to `internal' parts of other
  1682. classes (coupling).  The `protected' parts of a class are more likely to change
  1683. than the `public' parts.
  1684.  
  1685. ==============================================================================
  1686.  
  1687. --
  1688. Marshall Cline
  1689. --
  1690. Marshall P. Cline, Ph.D. / Paradigm Shift, Inc / One Park St/Norwood, NY 13668
  1691. cline@parashift.com / 315-353-6100 / FAX: 315-353-6110
  1692.  
  1693.  
  1694. From charnel!olivea!uunet!europa.eng.gtefsd.com!tsg.com!rpi!clarkson!news.clarkson.edu!cline Sat Jul 10 22:37:18 PDT 1993
  1695. Article: 40543 of comp.lang.c++
  1696. Newsgroups: comp.lang.c++,news.answers
  1697. Path: charnel!olivea!uunet!europa.eng.gtefsd.com!tsg.com!rpi!clarkson!news.clarkson.edu!cline
  1698. From: cline@sun.soe.clarkson.edu (Marshall Cline)
  1699. Subject: comp.lang.c++ FAQ (posting 3 of 4)
  1700. Message-ID: <CLINE.93Jul9064117@cheetah.clarkson.edu>
  1701. Sender: news@news.clarkson.edu
  1702. Nntp-Posting-Host: cheetah.ece.clarkson.edu
  1703. Reply-To: cline@parashift.com (Marshall Cline)
  1704. Organization: Paradigm Shift, Inc (Reuse/C++/OOD training, C++ libraries)
  1705. Date: Fri, 9 Jul 1993 11:41:17 GMT
  1706. Approved: news-answers-request@MIT.Edu
  1707. Expires: Mon, 9 Aug 1993 10:34:43 GMT
  1708. Lines: 855
  1709. Xref: charnel comp.lang.c++:40543 news.answers:10207
  1710.  
  1711. ==============================================================================
  1712.  
  1713.         ****  PART 12 -- Abstraction  ****
  1714.  
  1715. ==============================================================================
  1716.  
  1717. Q70: What's the big deal of separating interface from implementation?
  1718. A: Separating interface from implementation is a key to reusable software.
  1719. Interfaces are a company's most valuable resources.  Designing an interface
  1720. takes longer than whipping together a concrete class which fulfills that
  1721. interface.  Furthermore interfaces require the resources of more expensive
  1722. people (for better and worse, most companies separate `designers' from
  1723. `coders').  Since they're so valuable, they should be protected from being
  1724. tarnished by data structures and other artifacts of the implementation (any
  1725. data structures you put in a class can never be `revoked' by a derived class,
  1726. which is why you want to `separate' the interface from the implementation).
  1727.  
  1728. ==============================================================================
  1729.  
  1730. Q71: How do I separate interface from implementation in C++ (like Modula-2)?
  1731. A: Short answer: use an ABC (see next question for what an ABC is).
  1732.  
  1733. ==============================================================================
  1734.  
  1735. Q72: What is an ABC (`abstract base class')?
  1736. A: An ABC corresponds to an abstract concept.  If you asked a Mechanic if he
  1737. repaired Vehicles, he'd probably wonder what *kind* of Vehicle you had in mind.
  1738. Chances are he doesn't repair space shuttles, ocean liners, bicycles, and
  1739. volkswaggon beetles too.  The problem is that the term `Vehicle' is an abstract
  1740. concept; you can't build one until you know what kind of vehicle to build.  In
  1741. C++, you'd make Vehicle be an ABC, with Bicycle, SpaceShuttle, etc, being
  1742. subclasses (an OceanLiner is-a-kind-of-a Vehicle).
  1743.  
  1744. In real-world OOP, ABCs show up all over the place.  Technically, an ABC is a
  1745. class that has one or more pure virtual member functions (see next question).
  1746. You cannot make an object (instance) of an ABC.
  1747.  
  1748. ==============================================================================
  1749.  
  1750. Q73: What is a `pure virtual' member function?
  1751. A: Some member functions exist in concept, but can't have any actual defn.  Ex:
  1752. Suppose I asked you to draw a Shape at location (x,y) that has size 7.2.  You'd
  1753. ask me `what kind of shape should I draw', since circles, squares, hexagons,
  1754. etc, are drawn differently.  In C++, we indicate the existence of the `draw()'
  1755. method, but we recognize it can only be defined in subclasses:
  1756.  
  1757.     class Shape {
  1758.     public:
  1759.       virtual void draw() const = 0;
  1760.       //...                     ^^^--- `=0' means it is `pure virtual'
  1761.     };
  1762.  
  1763. This pure virtual makes `Shape' an ABC.  The `const' says that invoking the
  1764. `draw()' method won't change the Shape object (ie: it won't move around on the
  1765. screen, change sizes, etc).  If you want, you can think of it as if the code
  1766. were at the NULL pointer.
  1767.  
  1768. Pure virtuals allow you to express the idea that any actual object created from
  1769. a [concrete] class derived from the ABC *will* have the indicated member fn,
  1770. but we simply don't have enough information to actually *define* it yet.  They
  1771. allow separation of interface from implementation, which ultimately allows
  1772. functionally equivalent subclasses to be produced that can `compete' in a free
  1773. market sense (a technical version of `market driven economics').
  1774.  
  1775. ==============================================================================
  1776.  
  1777. Q74: How can I provide printing for an entire hierarchy rooted at `class X'?
  1778. A: Provide a friend operator<< that calls a protected virtual function:
  1779.  
  1780.     class X {
  1781.     public:
  1782.       friend ostream& operator<< (ostream& o,const X& x)
  1783.         { x.print(o); return o; }
  1784.       //...
  1785.     protected:
  1786.       virtual void print(ostream& o) const;  //or `=0;' if `X' is abstract
  1787.     };
  1788.  
  1789. Now all subclasses of X merely provide their own `print(ostream&)const' member
  1790. function, and they all share the common `<<' operator.  Friends don't bind
  1791. dynamically, but this technique makes them *act* as if they were.
  1792.  
  1793. ==============================================================================
  1794.  
  1795. Q75: What is a `virtual destructor'?
  1796. A: In general, a virtual fn means to start at the class of the object itself,
  1797. not the type of the pointer/ref (`do the right thing based on the actual class
  1798. of' is a good way to remember it).  Virtual destructors (dtors) are no
  1799. different: start the destruction process `down' at the object's actual class,
  1800. rather than `up' at the ptr's class (ie: `destroy yourself using the *correct*
  1801. destruction routine').
  1802.  
  1803. Virtual destructors are so valuable that some people want compilers to holler
  1804. at you if you forget them.  In general there's only one reason *not* to make a
  1805. class' dtor virtual: if that class has no virtual fns, the introduction of the
  1806. first virtual fn imposes typically 4 bytes overhead in the size of each object
  1807. (there's a bit of magic for how C++ `does the right thing', and it boils down
  1808. to an extra ptr per object called the `virtual table pointer' or `vptr').
  1809.  
  1810. ==============================================================================
  1811.  
  1812. Q76: What is a `virtual constructor'?
  1813. A: Technically speaking, there is no such thing.  You can get the effect you
  1814. desire by a virtual `create_copy()' member fn (for copy constructing), or a
  1815. `create_similar()' member fn (also virtual) which constructs/creates a new
  1816. object of the same class but is `fresh' (like the `default' [zero parameter]
  1817. ctor would do).
  1818.  
  1819. The reason ctors can't be virtual is simple: a ctor turns raw bits into a
  1820. living object.  Until there's a living respondent to a message, you can't
  1821. expect a message to be handled `the right way'.  You can think of ctors as
  1822. `class' [static] functions, or as `factories' which churn out objects.
  1823. Thinking of ctors as `methods' attached to an object is misleading.
  1824.  
  1825. Here is an example of how you could use `create_copy()' and `create_similar()'
  1826. methods:
  1827.  
  1828.     class Set {            //normally this would be a template
  1829.     public:
  1830.       virtual void insert(int);    //Set of `int'
  1831.       virtual int  remove();
  1832.       //...
  1833.       virtual Set* create_copy() const = 0;    //pure virtual; Set is an ABC
  1834.       virtual Set* create_similar() const = 0;
  1835.       virtual ~Set() { }        //see on `virtual destructors' for more
  1836.     };
  1837.  
  1838.     class SetHT : public Set {
  1839.     public:
  1840.       //...
  1841.       Set* create_copy()    const { return new SetHT(*this); }
  1842.       Set* create_similar() const { return new SetHT(); }
  1843.     protected:
  1844.       //a hash table in here
  1845.     };
  1846.  
  1847. A SetHT is-a Set, so the return value is correct.  The invocation of
  1848. `SetHT(*this)' is that of copy construction (`*this' has type `const SetHT&').
  1849. Although `create_copy()' returns a new SetHT, the caller of create_copy()
  1850. merely knows he has a Set, not a SetHT (which is desirable in the case of
  1851. wanting a `virtual ctor').  `create_similar()' is similar, but it constructs an
  1852. `empty' SetHT.
  1853.  
  1854. Clients can use this as if they were `virtual constructors':
  1855.  
  1856.     void client_code(Set& s)
  1857.     {
  1858.       Set* s2 = s.create_copy();
  1859.       Set* s3 = s.create_similar();
  1860.       //...
  1861.       delete s2;    //relies on destructor being virtual!!
  1862.       delete s3;    // ditto
  1863.     }
  1864.  
  1865. This fn will work correctly regardless of how the Set is implemented (hash
  1866. table based, AVL tree based, etc).
  1867.  
  1868. See above on `separation of interface from implementation' for more.
  1869.  
  1870. ==============================================================================
  1871.  
  1872.         ****  PART 13 -- Style guidelines  ****
  1873.  
  1874. ==============================================================================
  1875.  
  1876. Q77: What are some good C++ coding standards?
  1877. A: Thank you for reading this answer rather than just trying to set your own
  1878. coding standards.  But please don't ask this question on Usenet.  Nearly every
  1879. software engineer has, at some point, felt that coding standards are or can be
  1880. used as a `power play'.  Furthermore some attempts to set C++ coding standards
  1881. have been made by those unfamiliar with the language and/or paradigm, so the
  1882. standards end up being based on what *was* the state-of-the-art when the
  1883. setters where writing code.  Such impositions generate an attitude of mistrust
  1884. for coding standards.  Obviously anyone who asks this question on Usenet wants
  1885. to be trained so they *don't* run off on their own ignorance, but nonetheless
  1886. the answers tend to generate more heat than light.
  1887.  
  1888. ==============================================================================
  1889.  
  1890. Q78: Are coding standards necessary?  sufficient?
  1891. A: Coding standards do not make non OO programmers into OO programmers.  Only
  1892. training and experience do that.  If they have merit, it is that coding
  1893. standards discourage the petty fragmentation that occurs when organizations
  1894. coordinate the activities of diverse groups of programmers.
  1895.  
  1896. But you really want more than a coding standard.  The structure provided by
  1897. coding standards gives neophytes one less degree of freedom to worry about,
  1898. however pragmatics go well beyond pretty-printing standards.  We actually need
  1899. a consistent *philosophy* of implementation.  Ex: strong or weak typing?
  1900. references or ptrs in our interface?  stream I/O or stdio?  should C++ code
  1901. call our C?  vise versa?  should we use ABCs?  polymorphism?  inheritance?
  1902. classes? encapsulation?  how should we handle exceptions?  etc.
  1903.  
  1904. Therefore what is needed is a `pseudo standard' for detailed *design*.  How can
  1905. we get this?  I recommend a two-pronged approach: training and libraries.
  1906. Training provides `intense instruction', and a high quality C++ class library
  1907. provides `long term instruction'.  There is a thriving commercial market for
  1908. both kinds of `training'.  Advice by organizations who have been through the
  1909. mill is consistent: Buy, Don't Build.  Buy libraries, buy training, buy tools.
  1910. Companies who have attempted to become a self-taught tool-shop as well as an
  1911. application/system shop have found success difficult.
  1912.  
  1913. Few argue that coding standards are `ideal', or even `good', however many feel
  1914. that they're necessary in the kind of organizations/situations described above.
  1915.  
  1916. The following questions provide some basic guidance in conventions and styles.
  1917.  
  1918. ==============================================================================
  1919.  
  1920. Q79: Should our organization determine coding standards from our C experience?
  1921. A: No matter how vast your C experience, no matter how advanced your C
  1922. expertise, being a good C programmer does not make you a good C++ programmer.
  1923. C programmers must learn to use the `++' part of `C++', or the results will be
  1924. lackluster.  People who want the `promise' of OOP, but who fail to put the `OO'
  1925. into OOP, are fooling themselves, and the balance sheet will show their folly.
  1926.  
  1927. C++ coding standards should be tempered by C++ experts.  Asking comp.lang.c++
  1928. is a start (but don't use the term `coding standard' in the question; instead
  1929. simply say, `what are the pros and cons of this technique?').  Seek out experts
  1930. who can help guide you away from pitfalls.  Get training.  Buy libraries and
  1931. see if `good' libraries pass your coding standards.  Do *not* set standards by
  1932. yourself unless you have considerable experience in C++.  Having no standard is
  1933. better than having a bad standard, since improper `official' positions `harden'
  1934. bad brain traces.  There is a thriving market for both C++ training and
  1935. libraries from which to pool expertise.
  1936.  
  1937. One more thing: whenever something is in demand, the potential for charlatans
  1938. increases.  Look before you leap.  Also ask for student-reviews from past
  1939. companies, since not even expertise makes someone a good communicator.
  1940. Finally, select a practitioner who can teach, not a full time teacher who has a
  1941. passing knowledge of the language/paradigm.
  1942.  
  1943. ==============================================================================
  1944.  
  1945. Q80: Should I declare locals in the middle of a fn or at the top?
  1946. A: Different people have different opinions about coding standards.  However
  1947. one thing we all should agree on is this: no style guide should impose undue
  1948. performance penalties.  The real reason C++ allows objects to be created
  1949. anywhere in the block is not style, but performance.
  1950.  
  1951. An object is initialized (constructed) the moment it is declared.  If you don't
  1952. have enough information to initialize an object until half way down the fn, you
  1953. can either initialize it to an `empty' value at the top then `assign' it later,
  1954. or initialize it correctly half way down the fn.  It doesn't take much
  1955. imagination to see that it's cheaper to get it right the first time than it is
  1956. to build it once, tear it down, then rebuild it again.  Simple examples show a
  1957. factor of 350% speed hit for simple classes like String.  Your mileage may
  1958. vary; surely the overall system degradation will be less that 300+%, but there
  1959. *will* be degradation.  *Unnecessary* degradation.
  1960.  
  1961. A common retort to the above is: `we'll provide "set" methods for every datum
  1962. in our objects, so the cost of construction will be spread out'.  This is worse
  1963. than the performance overhead, since now you're introducing a maintenance
  1964. nightmare.  Providing `set' methods for every datum is tantamount to public
  1965. data.  You've exposed your implementation technique to the world.  The only
  1966. thing you've hidden is the physical *names* of your subobjects, but the fact
  1967. that you're using a List and a String and a float (for example) is open for all
  1968. to see.  Maintenance generally consumes far more resources than run-time CPU.
  1969.  
  1970. Conclusion: in general, locals should be declared near their first use.  Sorry
  1971. that this isn't `familiar' to your C experts, but `new' doesn't necessarily
  1972. mean `bad'.
  1973.  
  1974. ==============================================================================
  1975.  
  1976. Q81: What source-file-name convention is best? `foo.C'? `foo.cc'? `foo.cpp'?
  1977. A: Most Un*x compilers accept `.C' for C++ source files, g++ preferring `.cc',
  1978. and cfront also accepting `.c'.  Most DOS and OS/2 compilers require `.cpp'
  1979. since DOS filesystems aren't case sensitive.  Some also advocate `.cxx'.  The
  1980. impact of this decision is not great, since a trivial shell script can rename
  1981. all .cc files into .C files.  The only files that would have to be modified are
  1982. the Makefiles, which is a very small piece of your maintenance costs.  Note
  1983. however that some versions of cfront accept a limited set of suffixes (ie: some
  1984. can't handle `.cc'; in these cases it is easier to tell `make' about CC's
  1985. convention than vise versa).
  1986.  
  1987. You can use `.C' on DOS or OS/2 if the compiler provides a command-line option
  1988. to tell it to always compile with C++ rules (ex: `ztc -cpp foo.C' for Zortech,
  1989. `bcc -P foo.C' for Borland, etc).
  1990.  
  1991. ==============================================================================
  1992.  
  1993. Q82: What header-file-name convention is best? `foo.H'? `foo.hh'? `foo.hpp'?
  1994. A: The naming of your source files is cheap since it doesn't affect your source
  1995. code.  Your substantial investment is your source code.  Therefore the names of
  1996. your header files must be chosen with much greater care.  The preprocessor will
  1997. accept whatever name you give it in the #include line, but whatever you choose,
  1998. you will want to plan on sticking with it for a long time, since it is more
  1999. expensive to change (though certainly not as difficult as, say, porting to a
  2000. new language).
  2001.  
  2002. Almost all vendors ship their C++ header files using a `.h' extension, which
  2003. means you can reliably do things like:
  2004.         #include <iostream.h>
  2005.  
  2006. Some sites use `.H' for their own internally developed header files, but most
  2007. simply use `.h'.
  2008.  
  2009. ==============================================================================
  2010.  
  2011. Q83: Are there any lint-like guidelines for C++?
  2012. A: Yes, there are some practices which are generally considered dangerous.
  2013. However none of these are universally `bad', since situations arise when
  2014. even the worst of these is needed:
  2015.  * a class `X's assignment operator should return `*this' as an `X&'
  2016.    (allows chaining of assignments)
  2017.  * a class with any virtual fns ought to have a virtual destructor
  2018.  * a class with any of {dtor, assignment-op, copy-ctor} generally needs all 3
  2019.  * a class `X's copy-ctor and assignment-op should have `const' in the param:
  2020.    `X::X(const X&)'  and  `X& X::operator=(const X&)'  respectively
  2021.  * always use initialization lists for class sub-objects rather than assignment
  2022.    the performance difference for user-defined classes can be substantial (3x!)
  2023.  * many assignment operators should start by testing if `we' are `them'; ex:
  2024.     X& X::operator=(const X& x)
  2025.     {
  2026.       if (this == &x) return *this;
  2027.       //...normal assignment duties...
  2028.       return *this;
  2029.     }
  2030.    sometimes there is no need to check, but these situations generally
  2031.    correspond to when there's no need for an explicit user-specified assignment
  2032.    op (as opposed to a compiler-synthesized assignment-op).
  2033.  * in classes that define both `+=', `+' and `=', `a+=b' and `a=a+b' should
  2034.    generally do the same thing; ditto for the other identities of builtin types
  2035.    (ex: a+=1 and ++a; p[i] and *(p+i); etc).  This can be enforced by writing
  2036.    the binary ops using the `op=' forms; ex:
  2037.     X operator+(const X& a, const X& b)
  2038.     {
  2039.       X ans = a;
  2040.       ans += b;
  2041.       return ans;
  2042.     }
  2043.    This way the `constructive' binary ops don't even need to be friends.  But
  2044.    it is sometimes possible to more efficiently implement common ops (ex: if
  2045.    class `X' is actually `String', and `+=' has to reallocate/copy string
  2046.    memory, it may be better to know the eventual length from the beginning).
  2047.  
  2048. ==============================================================================
  2049.  
  2050.         ****  PART 14 -- C++/Smalltalk differences and keys to learning C++  ****
  2051.  
  2052. ==============================================================================
  2053.  
  2054. Q84: Why does C++'s FAQ have a section on Smalltalk? Is this Smalltalk-bashing?
  2055. A: The two `major' OOPLs in the world are C++ and Smalltalk.  Due to its
  2056. popularity as the OOPL with the second largest user pool, many new C++
  2057. programmers come from a Smalltalk background.  This section answers the
  2058. questions:
  2059.  * what's different about the two languages
  2060.  * what must a Smalltalk-turned-C++ programmer know to master C++
  2061.  
  2062. This section does *!*NOT*!* attempt to answer the questions:
  2063.  * which language is `better'?
  2064.  * why is Smalltalk `bad'?
  2065.  
  2066. Nor is it an open invitation for some Smalltalk terrorist to slash my tires
  2067. while I sleep (on those rare occasions when I have time to rest these days :-).
  2068.  
  2069. ==============================================================================
  2070.  
  2071. Q85: What's the difference between C++ and Smalltalk?
  2072. A: There are many differences such as compiled vs perceived-as-interpreted,
  2073. pure vs hybrid, faster vs perceived-as-slower, etc.  Some of these aren't true
  2074. (ex: a large portion of a typical Smalltalk program can be compiled by current
  2075. implementations, and some Smalltalk implementations perform reasonably well).
  2076. But none of these affect the programmer as much as the following three issues:
  2077.  
  2078.     * static typing vs dynamic typing (`strong' and `weak' are synonyms)
  2079.     * how you use inheritance
  2080.     * value vs reference semantics
  2081.  
  2082. The first two differences are illuminated in the remainder of this section; the
  2083. third point is the subject of the section that follows.
  2084.  
  2085. If you're a Smalltalk programmer who wants to learn C++, you'd be very wise to
  2086. study the next three questions carefully.  Historically there have been many
  2087. attempts to `make' C++ look/act like Smalltalk, even though the languages are
  2088. very Very different.  This hasn't always led to failures, but the differences
  2089. are significant enough that it has led to a lot of needless frustration and
  2090. expense.  The quotable quote of the year goes to Bjarne Stroustrup at the `C++
  2091. 1995' panel discussion, 1990 C++-At-Work conference, discussing library design:
  2092.         `Smalltalk is the best Smalltalk around'.
  2093.  
  2094. ==============================================================================
  2095.  
  2096. Q86: What is `static typing', and how is it similar/dissimilar to Smalltalk?
  2097. A: Static (most say `strong') typing says the compiler checks the type-safety
  2098. of every operation *statically* (at compile-time), rather than to generate code
  2099. which will check things at run-time.  For example, the signature matching of fn
  2100. arguments is checked, and an improper match is flagged as an error by the
  2101. *compiler*, not at run-time.
  2102.  
  2103. In OO code, the most common `typing mismatch' is sending a message to an object
  2104. that the recipient isn't prepare to handle.  Ex: if class `X' has member fn f()
  2105. but not g(), and `x' is an instance of class X, then x.f() is legal and x.g()
  2106. is illegal.  C++ (statically/strongly typed) catches the error at compile time,
  2107. and Smalltalk (dynamically/weakly typed) catches `type' errors at run-time.
  2108. (Technically speaking, C++ is like Pascal [*pseudo* statically typed], since
  2109. ptr casts and unions can be used to violate the typing system; you probably
  2110. shouldn't use these constructs very much).
  2111.  
  2112. ==============================================================================
  2113.  
  2114. Q87: Which is a better fit for C++: `static typing' or `dynamic typing'?
  2115. A: The arguments over the relative goodness of static vs dynamic typing will
  2116. continue forever.  However one thing is clear: you should use a tool like it
  2117. was intended and designed to be used.  If you want to use C++ most effectively,
  2118. use it as a statically typed language.  C++ is flexible enough that you can
  2119. (via ptr casts, unions, and #defines) make it `look' like Smalltalk.
  2120.  
  2121. There are places where ptr casts and unions are necessary and even wholesome,
  2122. but they should be used carefully and sparingly.  A ptr cast tells the compiler
  2123. to believe you.  It effectively suspends the normal type checking facilities.
  2124. An incorrect ptr cast might corrupt your heap, scribble into memory owned by
  2125. other objects, call nonexistent methods, and cause general failures.  It's not
  2126. a pretty sight.  If you avoid these and related constructs, you can make your
  2127. C++ code both safer and faster -- anything that can be checked at compile time
  2128. is something that doesn't have to be done at run-time, one `pro' of strong
  2129. typing.
  2130.  
  2131. Even if you're in love with weak typing, please consider using C++ as a
  2132. strongly typed OOPL, or else please consider using another language that better
  2133. supports your desire to defer typing decisions to run-time.  Since C++ performs
  2134. 100% type checking decisions at compile time, there is *no* built-in mechanism
  2135. to do *any* type checking at run-time; if you use C++ as a weakly typed OOPL,
  2136. you put your life in your own hands.
  2137.  
  2138. ==============================================================================
  2139.  
  2140. Q88: How can you tell if you have a dynamically typed C++ class library?
  2141. A: One hint that a C++ class library is weakly typed is when everything is
  2142. derived from a single root class, usually `Object'.  Even more telling is the
  2143. implementation of the container classes (List, Stack, Set, etc): if these
  2144. containers are non-templates, and if their elements are inserted/extracted as
  2145. ptrs to `Object', the container will promote weak typing.  You can put an Apple
  2146. into such a container, but when you get it out, the compiler only knows that it
  2147. is derived from Object, so you have to do a pointer cast (a `down cast') to
  2148. cast it `down' to an Apple (you also might hope a lot that you got it right,
  2149. cause your blood is on your own head).
  2150.  
  2151. You can make the down cast `safe' by putting a virtual fn into Object such as
  2152. `are_you_an_Apple()' or perhaps `give_me_the_name_of_your_class()', but this
  2153. dynamic testing is just that: dynamic.  This coding style is the essence of
  2154. weak typing in C++.  You call a function that says `convert this Object into an
  2155. Apple or kill yourself if its not an Apple', and you've got weak typing: you
  2156. don't know if the call will succeed until run-time.
  2157.  
  2158. When used with templates, the C++ compiler can statically validate 99% of an
  2159. application's typing information (the figure `99%' is apocryphal; some claim
  2160. they always get 100%, others find the need to do persistence which cannot be
  2161. statically type checked).  The point is: C++ gets genericity from templates,
  2162. not from inheritance.
  2163.  
  2164. ==============================================================================
  2165.  
  2166. Q89: Will `standard C++' include any dynamic typing primitives?
  2167. A: Yep.
  2168.  
  2169. Note that the effect of a down-cast and a virtual fn call are similar: in the
  2170. member fn that results from the virtual fn call, the `this' ptr is a downcasted
  2171. version of what it used to be (it went from ptr-to-Base to ptr-to-Derived).
  2172. The difference is that the virtual fn call *always* works: it never makes the
  2173. wrong `down-cast' and it automatically extends itself whenever a new subclass
  2174. is created -- as if an extra `case' or `if/else' magically appearing in the
  2175. weak typing technique.  The other difference is that the client gives control
  2176. to the object rather than reasoning *about* the object.
  2177.  
  2178. ==============================================================================
  2179.  
  2180. Q90: How do you use inheritance in C++, and is that different from Smalltalk?
  2181. A: There are two reasons one might want to use inheritance: to share code, or
  2182. to express your interface compliance.  Ie: given a class `B' (`B' stands for
  2183. `base class', which is called `superclass' in Smalltalkese), a class `D' which
  2184. is derived from B is expressed this way:
  2185.  
  2186.     class B { /*...*/ };
  2187.     class D : public B { /*...*/ };
  2188.  
  2189. This says two distinct things: (1) the bits(data structure) + code(algorithms)
  2190. are inherited from B, and (2) `D's public interface is `conformal' to `B's
  2191. (anything you can do to a B, you can also do to a D, plus perhaps some other
  2192. things that only D's can do; ie: a D is-a-kind-of-a B).
  2193.  
  2194. In C++, one can use inheritance to mean:
  2195.     --> #2(is-a) alone (ex:you intend to override most/all inherited code)
  2196.     --> both #2(is-a) and #1(code-sharing)
  2197. but one should never Never use the above form of inheritance to mean
  2198.     --> #1(code-sharing) alone (ex: D really *isn't* a B, but...)
  2199.  
  2200. This is a major difference with Smalltalk, where there is only one form of
  2201. inheritance (C++ provides `private' inheritance to mean `share the code but
  2202. don't conform to the interface').  The Smalltalk language proper (as opposed to
  2203. coding practice) allows you to have the *effect* of `hiding' an inherited
  2204. method by providing an override that calls the `does not understand' method.
  2205. Furthermore Smalltalk allows a conceptual `is-a' relationship to exist *apart*
  2206. from the subclassing hierarchy (subtypes don't have to be subclasses; ex: you
  2207. can make something that `is-a Stack' yet doesn't inherit from `Stack').
  2208.  
  2209. In contrast, C++ is more restrictive about inheritance: there's no way to make
  2210. a `conceptual is-a' relationship without using inheritance (the C++ work-around
  2211. is to separate interface from implementation via ABCs).  The C++ compiler
  2212. exploits the added semantic information associated with public inheritance to
  2213. provide static typing.
  2214.  
  2215. ==============================================================================
  2216.  
  2217. Q91: What are the practical consequences of diffs in Smalltalk/C++ inheritance?
  2218. A: Since Smalltalk lets you make a subtype without making a subclass, one can
  2219. be very carefree in putting data (bits, representation, data structure) into a
  2220. class (ex: you might put a linked list into a Stack class).  After all, if
  2221. someone wants something that an array-based-Stack, they don't have to inherit
  2222. from Stack; they can go off and make effectively a stand-alone class (they
  2223. might even *inherit* from an Array class, even though they're not-a-kind-of-
  2224. Array!).
  2225.  
  2226. In C++, you can't be nearly as carefree.  Since only mechanism (method code),
  2227. but not representation (data bits) can be overridden in subclasses, you're
  2228. usually better off *not* putting the data structure in a class.  This leads to
  2229. the concept of Abstract Base Classes (ABCs), which are discussed in a separate
  2230. question.  You can change the algorithm but NOT the data structure.  Bits are
  2231. forever.
  2232.  
  2233. I like to think of the difference between an ATV and a Maseratti.  An ATV [all
  2234. terrain vehicle] is more fun, since you can `play around' by driving through
  2235. fields, streams, sidewalks and the like.  A Maseratti, on the other hand, gets
  2236. you there faster, but it forces you to stay on the road.  My advice to C++
  2237. programmers is simple: stay on the road.  Even if you're one of those people
  2238. who like the `expressive freedom' to drive through the bushes, don't do it in
  2239. C++; it's not a good `fit'.
  2240.  
  2241. Note that C++ compilers uphold the is-a semantic constraint only with `public'
  2242. inheritance.  Neither containment (has-a), nor private or protected inheritance
  2243. implies conformance.
  2244.  
  2245. ==============================================================================
  2246.  
  2247. Q92: Do you need to learn a `pure' OOPL before you learn C++?
  2248. A: The short answer is, No.
  2249.  
  2250. The medium answer length answer is: learning some `pure' OOPLs may *hurt*
  2251. rather than help.
  2252.  
  2253. The long answer is: read the previous questions on the difference between C++
  2254. and Smalltalk (the usual `pure' OOPL being discussed; `pure' means everything
  2255. is an object of some class; `hybrid' [like C++] means things like int, char,
  2256. and float are not instances of a class, hence aren't subclassable).
  2257.  
  2258. The `purity' of the OOPL doesn't make the transition to C++ any more or less
  2259. difficult; it is the weak typing and improper inheritance that is so hard to
  2260. get.  I've taught numerous people C++ with a Smalltalk background, and they
  2261. usually have just as hard a time as those who've never seen inheritance before.
  2262. In fact, my personal observation is that those with extensive experience with a
  2263. weakly typed OOPL (usually but not always Smalltalk) have a *harder* time,
  2264. since it's harder to *unlearn* habits than it is to learn the statically typed
  2265. way from the beginning.
  2266.  
  2267. ==============================================================================
  2268.  
  2269. Q93: What is the NIHCL?  Where can I get it?
  2270. A: NIHCL stands for `national-institute-of-health's-class-library'.
  2271. it can be acquired via anonymous ftp from [128.231.128.251]
  2272. in the file pub/nihcl-3.0.tar.Z
  2273.  
  2274. NIHCL (some people pronounce it `N-I-H-C-L', others pronounce it like `nickel')
  2275. is a C++ translation of the Smalltalk class library.  There are some ways where
  2276. NIHCL's use of weak typing helps (ex: persistent objects).  There are also
  2277. places where the weak typing it introduces create tension with the underlying
  2278. statically typed language.
  2279.  
  2280. A draft version of the 250pp reference manual is included with version 3.10
  2281. (gnu emacs TeX-info format).  It is not available via uucp, or via regular mail
  2282. on tape, disk, paper, etc (at least not from Keith Gorlen).
  2283.  
  2284. See previous questions on Smalltalk for more.
  2285.  
  2286. ==============================================================================
  2287.  
  2288.         ****  PART 15 -- Reference and value semantics  ****
  2289.  
  2290. ==============================================================================
  2291.  
  2292. Q94: What is value and/or reference semantics, and which is best in C++?
  2293. A: With reference semantics, assignment is a pointer-copy (ie: a *reference*).
  2294. Value (or `copy') semantics mean assignment copies the value, not just the
  2295. pointer.  C++ gives you the choice: use the assignment operator to copy the
  2296. value (copy/value semantics), or use a ptr-copy to copy a pointer (reference
  2297. semantics).  C++ allows you to override the assignment operator to do anything
  2298. your heart desires, however the default (and most common) choice is to copy the
  2299. *value*.  Smalltalk and Eiffel and CLOS and most other OOPLs force reference
  2300. semantics; you must use an alternate syntax to copy the value (clone,
  2301. shallowCopy, deepCopy, etc), but even then, these languages ensure that any
  2302. name of an object is actually a *pointer* to that object (Eiffel's `expanded'
  2303. classes allow a supplier-side work-around).
  2304.  
  2305. There are many pros to reference semantics, including flexibility and dynamic
  2306. binding (you get dynamic binding in C++ only when you pass by ptr or pass by
  2307. ref, not when you pass by value).
  2308.  
  2309. There are also many pros to value semantics, including speed.  `Speed' seems
  2310. like an odd benefit to for a feature that requires an object (vs a ptr) to be
  2311. copied, but the fact of the matter is that one usually accesses an object more
  2312. than one copies the object, so the cost of the occasional copies is (usually)
  2313. more than offset by the benefit of having an actual object rather than a ptr to
  2314. an object.
  2315.  
  2316. There are three cases when you have an actual object as opposed to a pointer to
  2317. an object: local vars, global/static vars, and fully contained subobjects in a
  2318. class.  The most common & most important of these is the last (`containment').
  2319.  
  2320. More info about copy-vs-reference semantics is given in the next questions.
  2321. Please read them all to get a balanced perspective.  The first few have
  2322. intentionally been slanted toward value semantics, so if you only read the
  2323. first few of the following questions, you'll get a warped perspective.
  2324.  
  2325. Assignment has other issues (ex: shallow vs deep copy) which are not covered
  2326. here.
  2327.  
  2328. ==============================================================================
  2329.  
  2330. Q95: What is `virtual data', and how-can / why-would I use it in C++?
  2331. A: Virtual data isn't strictly a `part' of C++, however it can be simulated.
  2332. It's not entirely pretty, but it works.  First we'll cover what it is and how
  2333. to simulate it, then conclude with why it isn't `part' of C++.
  2334.  
  2335. Consider classes Vec (like an array of int) and SVec (a stretchable Vec; ie:
  2336. SVec overrides operator[] to automatically stretch the number of elements
  2337. whenever a large index is encountered).  SVec inherits from Vec.  Naturally
  2338. Vec's subscript operator is virtual.
  2339.  
  2340. Now consider a VStack class (Vec-based-Stack).  Naturally this Stack has a
  2341. capacity limited by the fixed number of elements in the underlying Vec data
  2342. structure.  Then someone comes along and wants an SVStack class (SVec based
  2343. Stack).  For some reason, they don't want to merely modify VStack (say, because
  2344. there are many users already using it).
  2345.  
  2346. The obvious choice then would be to inherit SVStack from VStack, however
  2347. then there'd be *two* Vecs in an SVStack object (one explicitly in VStack,
  2348. the other as the base class subobject in the SVec which is explicitly in
  2349. the SVStack).  That's a lot of extra baggage.  There are at least 2 solns:
  2350.  * break the is-a link between SVStack and VStack, text-copy the code from
  2351.    VStack and manually change `Vec' to `SVec'.
  2352.  * activate some sort of virtual data, so subclasses can change the
  2353.    class of subobjects.
  2354.  
  2355. To effect virtual data, we need to change the Vec subobject from a physically
  2356. contained subobject into a ptr pointing to a dynamically allocated subobject:
  2357.  
  2358. _____original_____        |_____to_support_virtual_data_____
  2359. class VStack {            | class VStack {
  2360. public:                | public:
  2361.   VStack(int cap=10)        |   VStack(int cap=10)
  2362.     : v(cap), sp(0) { }        |     : v(*new Vec(cap)), sp(0) { } //FREESTORE
  2363.   void push(int x) {v[sp++]=x;}    |   void push(int x) {v[sp++]=x;}   //no change
  2364.   int  pop()  {return v[--sp];}    |   int  pop()  {return v[--sp];}   //no change
  2365.  ~VStack() { }   //unnecessary    |  ~VStack()    {delete &v;}        //NECESSARY
  2366. protected:            | protected:
  2367.   Vec v;  //where data stored    |   Vec& v; //where data is stored
  2368.   int sp; //stack pointer    |   int sp; //stack pointer
  2369. };                | };
  2370.  
  2371. Now the subclass has a shot at overriding the defn of the object referred to as
  2372. `v'.  Ex: basically SVStack merely needs to bind a new SVec to `v', rather than
  2373. letting VStack bind the Vec.  However classes can only initialize their *own*
  2374. subobjects in an init-list.  Even if I had used a ptr rather than a ref, VStack
  2375. must be prevented from allocating its own `Vec'.  The way we do this is to add
  2376. another ctor to VStack that takes a Vec& and does *not* allocate a Vec:
  2377.  
  2378.     class VStack {
  2379.     protected:
  2380.       VStack(Vec& vv) : v(vv), sp(0) { }    //`protected' constructor!
  2381.     //...                    //(prevents public access)
  2382.     };
  2383.  
  2384. That's all there is to it!  Now the subclass (SVStack) can be defined as:
  2385.  
  2386.     class SVStack : public VStack {
  2387.     public:
  2388.       SVStack(int init_cap=10) : VStack(*new SVec(init_cap)) { }
  2389.     };
  2390.  
  2391. Pros:    * implementation of SVStack is a one-liner
  2392.     * SVStack shares code with VStack
  2393.  
  2394. Cons:    * extra layer of indirection to access the Vec
  2395.     * extra freestore allocations (both new and delete)
  2396.     * extra dynamic binding (reason given in next question)
  2397.  
  2398. We succeeded at making *our* job easier as implementor of SVStack, but all
  2399. clients pay for it.  It wouldn't be so bad if clients of SVStack paid for it,
  2400. after all, they chose to use SVStack (you pay for it if you use it).  However
  2401. the `optimization' made the users of the plain VStack pay as well!
  2402.  
  2403. See the question after the next to find out how much the client's `pay'.  Also:
  2404. *PLEASE* read the few questions that follow the next one too (YOU WILL NOT GET
  2405. A BALANCED PERSPECTIVE WITHOUT THE OTHERS).
  2406.  
  2407. ==============================================================================
  2408.  
  2409. Q96: What's the difference between virtual data and dynamic data?
  2410. A: The easiest way to see the distinction is by an analogy with `virtual fns':
  2411. A virtual member fn means the declaration (signature) must stay the same in
  2412. subclasses, but the defn (body) can be overridden.  The overriddenness of an
  2413. inherited member fn is a static property of the subclass; it doesn't change
  2414. dynamically throughout the life of any particular object, nor is it possible
  2415. for distinct objects of the subclass to have distinct defns of the member fn.
  2416.  
  2417. Now go back and re-read the previous paragraph, but make these substitutions:
  2418.     `member fn' --> `subobject'
  2419.     `signature' --> `type'
  2420.     `body'      --> `exact class'
  2421. After this, you'll have a working defn of virtual data.
  2422.  
  2423. `Per-object member fns' (a member fn `f()' which is potentially different in
  2424. any given instance of an object) could be handled by burying a function ptr in
  2425. the object, then setting the (const) fn ptr during construction.
  2426.  
  2427. `Dynamic member fns' (member fns which change dynamically over time) could also
  2428. be handled by function ptrs, but this time the fn ptr would not be const.
  2429.  
  2430. In the same way, there are three distinct concepts for data members:
  2431.  * virtual data: the defn (`class') of the subobject is overridable in
  2432.    subclasses provided its declaration (`type') remains the same, and this
  2433.    overriddenness is a static property of the [sub]class.
  2434.  * per-object-data: any given object of a class can instantiate a different
  2435.    conformal (same type) subobject upon initialization (usually a `wrapper'
  2436.    object), and the exact class of the subobject is a static property of the
  2437.    object that wraps it.
  2438.  * dynamic-data: the subobject's exact class can change dynamically over time.
  2439.  
  2440. The reason they all look so much the same is that none of this is `supported'
  2441. in C++.  It's all merely `allowed', and in this case, the mechanism for faking
  2442. each of these is the same: a ptr to a (probably abstract) base class.  In a
  2443. language that made these `first class' abstraction mechanisms, the difference
  2444. would be more striking, since they'd each have a different syntactic variant.
  2445.  
  2446. ==============================================================================
  2447.  
  2448. Q97: Should class subobjects be ptrs to freestore allocated objs, or contained?
  2449. A: Usually your subobjects should actually be `contained' in the aggregate
  2450. class (but not always; `wrapper' objects are a good example of where you want a
  2451. a ptr/ref; also the N-to-1-uses-a relationship needs something like a ptr/ref).
  2452.  
  2453. There are three reasons why fully contained subobjects have better performance
  2454. than ptrs to freestore allocated subobjects:
  2455.     * extra layer to indirection every time you need to access subobject
  2456.     * extra freestore allocations (`new' in ctor, `delete' in dtor)
  2457.     * extra dynamic binding (reason given later in this question)
  2458.  
  2459. ==============================================================================
  2460.  
  2461. Q98: What are relative costs of the 3 performance hits of allocated subobjects?
  2462. A: The three performance hits are enumerated in the previous question:
  2463.  * By itself, an extra layer of indirection is small potatoes.
  2464.  * Freestore allocations can be a big problem (standard malloc's performance
  2465.    degrades with more small freestore allocations; OO s/w can easily become
  2466.    `freestore bound' unless you're careful).
  2467.  * Extra dynamic binding comes from having a ptr rather than an object.
  2468.    Whenever the C++ compiler can know an object's *exact* class, virtual fn
  2469.    calls can be *statically* bound, which allows inlining.  Inlining allows
  2470.    zillions (would you believe half a dozen :-) optimization opportunities
  2471.    such as procedural integration, register lifetime issues, etc.  The C++
  2472.    compiler can know an object's exact class in three circumstances: local
  2473.    variables, global/static variables, and fully-contained subobjects.
  2474.  
  2475. Thus fully-contained subobjects allow significant optimizations that wouldn't
  2476. be possible under the `subobjects-by-ptr' approach (this is the main reason
  2477. that languages which enforce reference-semantics have `inherent' performance
  2478. problems).
  2479.  
  2480. ==============================================================================
  2481.  
  2482. Q99: What is an `inline virtual member fn'?  Are they ever actually `inlined'?
  2483. A: A inline virtual member fn is a member fn that is inline and virtual :-).
  2484. The second question is much harder to answer.  The short answer is `Yes, but'.
  2485.  
  2486. A virtual call (msg dispatch) via a ptr or ref is always resolved dynamically
  2487. (at run-time).  In these situations, the call is never inlined, since the
  2488. actual code may be from a derived class that was created after the caller was
  2489. compiled.
  2490.  
  2491. The difference between a regular fn call and a virtual fn call is rather small.
  2492. In C++, the cost of dispatching is rarely a problem.  But the lack of inlining
  2493. in any language can be very Very significant.  Ex: simple experiments will show
  2494. the difference to get as bad as an order of magnitude (for zillions of calls to
  2495. insignificant member fns, loss of inlining virtual fns can result in 25X speed
  2496. degradation! [Doug Lea, `Customization in C++', proc Usenix C++ 1990]).
  2497.  
  2498. This is why endless debates over the actual number of clock cycles required to
  2499. do a virtual call in language/compiler X on machine Y are largely meaningless.
  2500. Ie: many language implementation vendors make a big stink about how good their
  2501. msg dispatch strategy is, but if these implementations don't *inline* method
  2502. calls, the overall system performance would be poor, since it is inlining
  2503. --*not* dispatching-- that has the greatest performance impact.
  2504.  
  2505. NOTE: PLEASE READ THE NEXT TWO QUESTIONS TO SEE THE OTHER SIDE OF THIS COIN!
  2506.  
  2507. ==============================================================================
  2508.  
  2509. Q100: Sounds like I should never use reference semantics, right?
  2510. A: Wrong.
  2511.  
  2512. Reference semantics is A Good Thing.  We can't live without pointers.  We just
  2513. don't want our s/w to be One Gigantic Pointer.  In C++, you can pick and choose
  2514. where you want reference semantics (ptrs/refs) and where you'd like value
  2515. semantics (where objects physically contain other objects etc).  In a large
  2516. system, there should be a balance.  However if you implement absolutely
  2517. *everything* as a pointer, you'll get enormous speed hits.
  2518.  
  2519. Objects near the problem skin are larger than higher level objects.  The
  2520. *identity* of these `problem space' abstractions is usually more important than
  2521. their `value'.  These combine to indicate reference semantics should be used
  2522. for problem-space objects (Booch says `Entity Abstractions'; see on `Books').
  2523.  
  2524. The question arises: is reference semantics likely to cause a performance
  2525. problem in these `entity abstractions'?  The key insight in answering this
  2526. question is that the relative interaction frequency is much lower for problem
  2527. skin abstractions than for low level server objects.
  2528.  
  2529. Thus we have an *ideal* situation in C++: we can choose reference semantics for
  2530. objects that need unique identity or that are too large to copy, and we can
  2531. choose value semantics for the others.  The result is very likely to be that
  2532. the highest frequency objects will end up with value semantics.  Thus we
  2533. install flexibility only where it doesn't hurt us, and performance where we
  2534. need it most!
  2535.  
  2536. These are some of the many issues the come into play with real OO design.
  2537. OO/C++ mastery takes time and high quality training.
  2538. That's the investment-price you pay for a powerful tool.
  2539.  
  2540.     <<<<DON'T STOP NOW!  READ THE NEXT QUESTION TOO!!>>>>
  2541.  
  2542. ==============================================================================
  2543.  
  2544. Q101: Does the poor performance of ref semantics mean I should pass-by-value?
  2545. A: No.  In fact, `NO!' :-)
  2546.  
  2547. The previous questions were talking about *subobjects*, not parameters.  Pass-
  2548. by-value is usually a bad idea when mixed with inheritance (larger subclass
  2549. objects get `sliced' when passed by value as a base class object).  Generally,
  2550. objects that are part of an inheritance hierarchy should be passed by ref or by
  2551. ptr, but not by value, since only then do you get the (desired) dynamic
  2552. binding.
  2553.  
  2554. Unless compelling reasons are given to the contrary, subobjects should be by
  2555. value and parameters should be by reference.  The discussion in the previous
  2556. few questions indicates some of the `compelling reasons' for when subobjects
  2557. should be by reference.
  2558.  
  2559. ==============================================================================
  2560.  
  2561. --
  2562. Marshall Cline
  2563. --
  2564. Marshall P. Cline, Ph.D. / Paradigm Shift, Inc / One Park St/Norwood, NY 13668
  2565. cline@parashift.com / 315-353-6100 / FAX: 315-353-6110
  2566.  
  2567.  
  2568. From charnel!olivea!uunet!europa.eng.gtefsd.com!tsg.com!rpi!clarkson!news.clarkson.edu!cline Sat Jul 10 22:37:28 PDT 1993
  2569. Article: 40544 of comp.lang.c++
  2570. Newsgroups: comp.lang.c++,news.answers
  2571. Path: charnel!olivea!uunet!europa.eng.gtefsd.com!tsg.com!rpi!clarkson!news.clarkson.edu!cline
  2572. From: cline@sun.soe.clarkson.edu (Marshall Cline)
  2573. Subject: comp.lang.c++ FAQ (posting 4 of 4)
  2574. Message-ID: <CLINE.93Jul9064214@cheetah.clarkson.edu>
  2575. Sender: news@news.clarkson.edu
  2576. Nntp-Posting-Host: cheetah.ece.clarkson.edu
  2577. Reply-To: cline@parashift.com (Marshall Cline)
  2578. Organization: Paradigm Shift, Inc (Reuse/C++/OOD training, C++ libraries)
  2579. Date: Fri, 9 Jul 1993 11:42:14 GMT
  2580. Approved: news-answers-request@MIT.Edu
  2581. Expires: Mon, 9 Aug 1993 10:35:38 GMT
  2582. Lines: 912
  2583. Xref: charnel comp.lang.c++:40544 news.answers:10208
  2584.  
  2585. ==============================================================================
  2586.  
  2587.         ****  PART 16 -- Linkage-to/relationship-with C  ****
  2588.  
  2589. ==============================================================================
  2590.  
  2591. Q102: How can I call a C function `f()' from C++ code?
  2592. A: Tell the C++ compiler that it is a C function:  extern "C" void f();
  2593. Be sure to include the full function prototype.  A block of many C functions
  2594. can be grouped via braces, as in:
  2595.  
  2596.     extern "C" {
  2597.       void* malloc(size_t);
  2598.       char* strcpy(char* dest, const char* src);
  2599.       int   printf(const char* fmt, ...);
  2600.     }
  2601.  
  2602. ==============================================================================
  2603.  
  2604. Q103: How can I create a C++ function `f()' that is callable by my C code?
  2605. A: Use the same `extern "C" f()' construct as detailed in the previous
  2606. question, only then proceed to actually define the function in your C++ module.
  2607. The compiler will ensure that the external information sent to the linker uses
  2608. C calling conventions and name mangling (ex: preceded by a single underscore).
  2609. Obviously you can't make several overloaded fns simultaneously callable by a C
  2610. program, since name overloading isn't supported by C.
  2611.  
  2612. Caveats and implementation dependencies:
  2613. * your `main()' should be compiled with your C++ compiler.
  2614. * your C++ compiler should direct the linking process.
  2615.  
  2616. ==============================================================================
  2617.  
  2618. Q104: Why's the linker giving errors for C/C++ fns being called from C++/C fns?
  2619. A: See the previous two questions on how to use `extern "C"'.
  2620.  
  2621. ==============================================================================
  2622.  
  2623. Q105: How can I pass an object of a C++ class to/from a C function?
  2624. A: Here's an example of one that will work (be sure to read the tail of this
  2625. answer which details when such a scheme will *not* work):
  2626.  
  2627.     /****** C/C++ header file: X.h ******/
  2628.     #ifdef __cplusplus    /*`__cplusplus' is #defined iff compiler is C++*/
  2629.       extern "C" {
  2630.     #endif
  2631.  
  2632.     #ifdef __STDC__
  2633.       extern int c_fn(struct X*);        /* ANSI-C prototypes */
  2634.       extern struct X* cplusplus_callback_fn(struct X*);
  2635.     #else
  2636.       extern int c_fn();            /* K&R style */
  2637.       extern struct X* cplusplus_callback_fn();
  2638.     #endif
  2639.  
  2640.     #ifdef __cplusplus
  2641.       }
  2642.     #endif
  2643.  
  2644.     #ifdef __cplusplus
  2645.       class X {
  2646.         int a;
  2647.       public:
  2648.         X();
  2649.         void frob(int);
  2650.       };
  2651.     #endif
  2652.  
  2653. Then, in file `X.C':
  2654.  
  2655.     #include "X.h"
  2656.     X::X() : a(0) { }
  2657.     void X::frob(int aa) { a = aa; }
  2658.  
  2659.     X* cplusplus_callback_fn(X* x)
  2660.     {
  2661.       x->frob(123);
  2662.       return x;
  2663.     }
  2664.  
  2665. In C++ file `main.C':
  2666.  
  2667.     #include "X.h"
  2668.  
  2669.     int main()
  2670.     {
  2671.       X x;
  2672.       c_fn(&x);
  2673.       return 0;
  2674.     }
  2675.  
  2676. Finally, in a C file `c-fn.c':
  2677.  
  2678.     #include "X.h"
  2679.  
  2680.     int c_fn(struct X* x)
  2681.     {
  2682.       if (cplusplus_callback_fn(x))
  2683.         do_one_thing();
  2684.       else
  2685.         do_something_else();
  2686.       return something();
  2687.     }
  2688.  
  2689. Passing ptrs to C++ objects to/from C fns will FAIL if you pass and get back
  2690. something that isn't *exactly* the same pointer, such as passing a base class
  2691. ptr and receiving a derived class ptr (this fails when multiple inheritance is
  2692. involved, since C fails to do pointer-conversion properly).
  2693.  
  2694. ==============================================================================
  2695.  
  2696. Q106: Can my C function access data in an object of a C++ class?
  2697. A: Sometimes.
  2698.  
  2699. (First read the previous question on passing C++ objects to/from C functions.)
  2700. You can safely access a C++ object's data from a C function if the C++ class:
  2701.  * has no virtual functions (including inherited virtual fns)
  2702.  * has all its data in the same access-level section (private/protected/public)
  2703.  * has no fully-contained subobjects with virtual fns
  2704.  
  2705. If the C++ class has any base classes at all (or if any fully contained
  2706. subobjects have base classes), accessing the data will *technically* be
  2707. non-portable, since class layout under inheritance isn't imposed by the
  2708. language.  However in practice, all C++ compilers do it the same way: the base
  2709. class object appears first (in left-to-right order in the event of multiple
  2710. inheritance), and subobjects follow.
  2711.  
  2712. Furthermore you can often (but less than always) assume a `void*' appears in
  2713. the object at the location of the first virtual function.  This is trickier,
  2714. since the first virtual function is often in a different access specifier
  2715. section than the data members.  Even the use of a single pointer is not
  2716. required by the language (but this is the way `everyone' does it).
  2717.  
  2718. If the class has any virtual base classes, it is more complicated and less
  2719. portable.  One common implementation technique is for objects to contain an
  2720. object of the virtual base class (V) last (regardless of where `V' shows up as
  2721. a virtual base class in the inheritance DAG), with the rest of the object's
  2722. parts appearing in the normal order.  Every class that has V as a virtual base
  2723. class actually has a *pointer* to the V part of the final object.
  2724.  
  2725. ==============================================================================
  2726.  
  2727. Q107: Why do I feel like I'm `further from the machine' in C++ as opposed to C?
  2728. A: Because you are.  Being an OOPL, C++ allows you to directly model the
  2729. problem domain itself (obviously OOD is more complex than this, but a good
  2730. start at `finding the objects' is to model the nouns in the problem domain).
  2731. By modeling the problem domain, the system interacts in the language of the
  2732. problem domain rather than in the language of the solution domain.
  2733.  
  2734. One of C's great strengths is the fact that it has `no hidden mechanism'.  What
  2735. you see is what you get.  You can read a C program and `see' every clock cycle.
  2736. This is not the case in C++; overloaded operators are a case in point.  Old
  2737. line C programmers (such as many of us once were) are often ambivalent about
  2738. this feature, but soon we realize that it provides a level of abstraction and
  2739. economy of expression which lowers maintenance costs without destroying runtime
  2740. performance.
  2741.  
  2742. Naturally you can write assembly code in any language; using C++ doesn't
  2743. guarantee any particular level of quality, reusability, abstraction, or any
  2744. other measure of `goodness'.  C++ doesn't try to make it impossible for bad
  2745. programmers to write bad programs; it enables good programmers to write good
  2746. programs.
  2747.  
  2748. ==============================================================================
  2749.  
  2750.         ****  PART 17 -- Pointers to member functions  ****
  2751.  
  2752. ==============================================================================
  2753.  
  2754. Q108: What is the type of `ptr-to-member-fn'?  Is it diffn't from `ptr-to-fn'?
  2755. A: A member fn of class X has type:  Returntype (X::*)(Argtypes)
  2756.    while a plain function has type:  Returntype (*)   (Argtypes)
  2757.  
  2758. ==============================================================================
  2759.  
  2760. Q109: How can I ensure `X's objects are only created with new, not on the stack?
  2761. A: Make constructors protected and define `friend' or `static' fns that return
  2762. a ptr to objects created via `new' (the ctors must be protected rather than
  2763. private, otherwise you couldn't derive from the class).  Ex:
  2764.  
  2765.     class X {    //only want to allow dynamicly allocated X's
  2766.     public:
  2767.       static X* create()           { return new X();  }
  2768.       static X* create(int i)      { return new X(i); }
  2769.       static X* create(const X& x) { return new X(x); }
  2770.     protected:
  2771.                X();
  2772.                X(int i);
  2773.                X(const X& x);
  2774.       virtual ~X();
  2775.     };
  2776.  
  2777.     X* Xptr = X::create(5);
  2778.  
  2779. ==============================================================================
  2780.  
  2781. Q110: How do I pass a ptr to member fn to a signal handler,X event callback,etc?
  2782. A: Because a member function is meaningless without an object to invoke it on,
  2783. you can't do this directly (if `X' were rewritten in C++, it would probably
  2784. pass references to *objects* around, not just pointers to fns; naturally the
  2785. objects would embody the required function and probably a whole lot more).
  2786.  
  2787. As a patch for existing software, use a free function as a wrapper which takes
  2788. an object obtained through some other technique (held in a global, perhaps) and
  2789. calls the desired member function.  There is one exception: static member
  2790. functions do not require an actual object to be invoked, and ptrs-to-static-
  2791. member-fns are type compatible with regular ptrs-to-fns (see ARM p.25, 158).
  2792.  
  2793. Ex: suppose you want to call X::memfn() on interrupt:
  2794.  
  2795.     class X {
  2796.     public:
  2797.              void memfn();
  2798.       static void staticmemfn();    //a static member fn can handle it
  2799.       //...
  2800.     };
  2801.  
  2802.     //wrapper fn remembers the object on which to invoke memfn in a static var:
  2803.     static X* object_which_will_handle_signal;
  2804.     void X_memfn_wrapper() { object_which_will_handle_signal.memfn(); }
  2805.  
  2806.     main()
  2807.     {
  2808.       /* signal(SIGINT, X::memfn); */   //Can NOT do this
  2809.       signal(SIGINT, X_memfn_wrapper);  //Ok
  2810.       signal(SIGINT, X::staticmemfn);   //Also Ok
  2811.     }
  2812.  
  2813. ==============================================================================
  2814.  
  2815. Q111: Why am I having trouble taking the address of a C++ function?
  2816. Short ans: Please read previous question first; this is a corollary.
  2817.  
  2818. Long ans: In C++, member fns have an implicit parameter which points to the
  2819. object (the `this' ptr inside the member fn).  Normal C fns can be thought of
  2820. as having a different calling convention from member fns, so the types of their
  2821. ptrs (ptr-to-member-fn vs ptr-to-fn) are different and incompatible.  C++
  2822. introduces a new type of ptr, called a ptr-to-member, which can only be invoked
  2823. by providing an object (see ARM 5.5).  Do NOT attempt to `cast' a ptr-to-mem-fn
  2824. into a ptr-to-fn; the result is undefined and probably disastrous; a ptr-to-
  2825. member-fn is NOT required to contain the machine addr of the appropriate fn
  2826. (see ARM, 8.1.2c, p.158).  As was said in the last example, if you want a
  2827. regular C fn ptr, use either a top-level (non-class) fn, or a `static' (class)
  2828. member fn.
  2829.  
  2830. ==============================================================================
  2831.  
  2832. Q112: How do I declare an array of pointers to member functions?
  2833. A: Use the following declaration:
  2834.  
  2835.     class Frob {
  2836.     public:
  2837.       Rettype f(T1 x, T2 y);
  2838.       Rettype g(T1 x, T2 y);
  2839.       Rettype h(T1 x, T2 y);
  2840.       Rettype i(T1 x, T2 y);
  2841.       //...
  2842.     };
  2843.  
  2844.     Rettype (Frob::*fn_ptr[3])(T1,T2) = { &Frob::f, &Frob::g, &Frob::h };
  2845.  
  2846. You can make the array declaration somewhat clearer with a typedef:
  2847.     typedef  Rettype (Frob::*Frob_member_ptr)(T1,T2);
  2848.     //...
  2849.     Frob_member_ptr fn_ptr[3] = { &Frob::f, &Frob::g, &Frob::h };
  2850.  
  2851. To call one of the functions on an object `frob', use:
  2852.     Frob frob;
  2853.     //...
  2854.     (frob.*fn_ptr[i])(x, y);
  2855.  
  2856. You can make the call somewhat clearer using a #define:
  2857.     #define  apply_member_fn(object,fn)   ((object).*(fn))
  2858.     //...
  2859.     apply_member_fn(frob,fn_ptr[i])(x, y)
  2860.  
  2861. ==============================================================================
  2862.  
  2863.         ****  PART 18 -- Container classes and templates  ****
  2864.  
  2865. ==============================================================================
  2866.  
  2867. Q113: How can I insert/access/change elements from a linked list/hashtable/etc?
  2868. A: I'll use a `inserting into a linked list' as a prototypical example.  The
  2869. obvious approach is to allow insertion at the head and tail of the list, but
  2870. that would produce a library that is too weak (a weak library is almost worse
  2871. than no library).  Whenever encapsulation frustrates rather than helps a user,
  2872. it may be that the class' public interface needs enhancing.  If class List only
  2873. supports adding at the front and tail, it *definitely* needs more strength.
  2874.  
  2875. This answer will be a lot to swallow for novice C++'ers, so I'll give a couple
  2876. of options.  As usual, the first is easiest, while the second option is better.
  2877. I also give a thumbnail sketch of a third option, which has certain advantages
  2878. and disadvantages over the second option.
  2879.  
  2880. [1] Empower the List with a `viewport' or `cursor' that references an arbitrary
  2881. list element.  Implies adding member fns to List such as advance(), backup(),
  2882. atend(), atbegin(), rewind(), fastforward(), and current().  `current()'
  2883. returns the element of the List that is currently `under the cursor'.  Finally
  2884. you'll need to add a few more member fns to *mutate* the list, such as
  2885. changeto(X), insert(X), remove(), etc.
  2886.  
  2887. [2] Provide a separate class called ListIter.  ListIter has member fns named
  2888. similar to the above (though probably with operator overloading, but that's
  2889. just syntactic sugar for member fns).  The List itself would have none of the
  2890. above mentioned member fns, and the ListIter would be a `friend' of List
  2891. (ListIter would have to have access to the innards of List; this allows the
  2892. world to have safe access abilities to List without violating encapsulation).
  2893.  
  2894. The reason option [2] is better becomes apparent when you use classes that only
  2895. support [1].  In particular, if you pass a List off to a subcall, you'd better
  2896. hope the subcall didn't warp the `cursor' around, or your code may fail.  Also,
  2897. if you try to get all pairs of elements, it's very hard if you only have one
  2898. cursor.  The distinct-class iterator concept removes these restrictions.  My
  2899. own class library uses these extensively, as will most any other commercial
  2900. grade class library.
  2901.  
  2902. Note that the options are not mutually exclusive; it is possible to provide
  2903. both [2] *and* [1], giving rise to the notion of a `primary' list position,
  2904. with instances of ListIter being somewhat secondary.
  2905.  
  2906. [3] The third possibility considers the entire iteration as an atomic event.  A
  2907. class is created which embodies this event.  The nice thing about this third
  2908. alternative is that the public access methods (which may be virtual fns) can be
  2909. avoided during the inner loop, thus enhancing performance.  The down side is
  2910. that you get extra object code in the application, since templates gain speed
  2911. by duplicating code.  This third technique is due to Andrew Koenig in a paper
  2912. published recently in JOOP [`Templates as interfaces', JOOP, 4, 5 (Sept 91)].
  2913. You can also see a taste of it in Bjarne Stroustrup's book, The C++ Programming
  2914. Language Second Edition (look for `Comparator' in the index).
  2915.  
  2916. ==============================================================================
  2917.  
  2918. Q114: What's the idea behind `templates'?
  2919. A: A template is a cookie-cutter that specifies how to cut cookies that all
  2920. look pretty much the same (although the cookies can be made of various kinds of
  2921. dough, they'll all have the same basic shape).  In the same way, a class
  2922. template is a cookie cutter to description of how to build classes that all
  2923. look basically the same, and a function template describes how to build similar
  2924. looking functions.
  2925.  
  2926. The questions about templates are in the `Containers' section since templates
  2927. are often used to build type safe containers (although this only scratches the
  2928. surface for how they can be used).  We will see how to use templates to build
  2929. container classes below.
  2930.  
  2931. ==============================================================================
  2932.  
  2933. Q115: What's the syntax / semantics for a `function template'?
  2934. A: Consider this function that swaps its two integer arguments:
  2935.  
  2936.     void swap(int& x, int& y)
  2937.     {
  2938.       int tmp = x;
  2939.       x = y;
  2940.       y = tmp;
  2941.     }
  2942.  
  2943. If we also had to swap floats, longs, Strings, Sets, and FileSystems, we'd get
  2944. pretty tired of coding lines that look almost identical except for the type.
  2945. Mindless repetition is an ideal job for a computer, hence a function template:
  2946.  
  2947.     template<class T>
  2948.     void swap(T& x, T& y)
  2949.     {
  2950.       T tmp = x;
  2951.       x = y;
  2952.       y = tmp;
  2953.     }
  2954.  
  2955. Every time we used `swap()' with a given pair of types, the compiler will go to
  2956. the above definition and will create yet another `template function' as an
  2957. instantiation of the above.  Ex:
  2958.  
  2959.     main()
  2960.     {
  2961.       int    i,j;  /*...*/  swap(i,j);  //instantiates a swap for `int'
  2962.       float  a,b;  /*...*/  swap(a,b);  //instantiates a swap for `float'
  2963.       char   c,d;  /*...*/  swap(c,d);  //instantiates a swap for `char'
  2964.       String s,t;  /*...*/  swap(s,t);  //instantiates a swap for `String'
  2965.     }
  2966.  
  2967. (note: a `template function' is the instantiation of a `function template').
  2968.  
  2969. ==============================================================================
  2970.  
  2971. Q116: What's the syntax / semantics for a `class template'?
  2972. A: Consider this container class of that acts like an array of integers:
  2973.  
  2974.     //this would go into a header file such as `Vec.h':
  2975.     class Vec {
  2976.     public:
  2977.       int         len()             const { return xlen;     }
  2978.       const int&  operator[](int i) const { xdata[check(i)]; }
  2979.             int&  operator[](int i)       { xdata[check(i)]; }
  2980.                   Vec(int L=10) : xlen(L), xdata(new int[L]) { /*verify*/ }
  2981.                  ~Vec()                   { delete [] xdata; }
  2982.     private:
  2983.       int  xlen;
  2984.       int* xdata;
  2985.       int  check(int i);  //return i if i>=0 && i<xlen else throw exception
  2986.     };
  2987.  
  2988.     //this would be part of a `.C' file such as `Vec.C':
  2989.     int Vec::check(int i)
  2990.     {
  2991.       if (i < 0 || i >= xlen) throw BoundsViol("Vec", i, xlen);
  2992.       return i;
  2993.     }
  2994.  
  2995. Just as with `swap()' above, repeating the above over and over for Vec of
  2996. float, char, String, Vec, Vec-of-Vec-of-Vec, etc, will become tedious.  Hence
  2997. we create a single class template:
  2998.  
  2999.     //this would go into a header file such as `Vec.h':
  3000.     template<class T>
  3001.     class Vec {
  3002.     public:
  3003.       int       len()             const { return xlen;     }
  3004.       const T&  operator[](int i) const { xdata[check(i)]; }
  3005.             T&  operator[](int i)       { xdata[check(i)]; }
  3006.                 Vec(int L=10) : xlen(L), xdata(new T[L]) { /*verify*/ }
  3007.                ~Vec()                   { delete [] xdata; }
  3008.     private:
  3009.       int  xlen;
  3010.       T*   xdata;
  3011.       int  check(int i);  //return i if i>=0 && i<xlen else throw exception
  3012.     };
  3013.  
  3014.     //this would be part of a `.C' file such as `Vec.C':
  3015.     template<class T>
  3016.     int Vec<T>::check(int i)
  3017.     {
  3018.       if (i < 0 || i >= xlen) throw BoundsViol("Vec", i, xlen);
  3019.       return i;
  3020.     }
  3021.  
  3022. Unlike template functions, template classes (instantiations of class templates)
  3023. need to be explicit about the parameters over which they are instantiating:
  3024.  
  3025.     main()
  3026.     {
  3027.       Vec<int>        vi;
  3028.       Vec<float>      vf;
  3029.       Vec<char*>      vc;
  3030.       Vec<String>     vs;
  3031.       Vec< Vec<int> > vv;
  3032.     }          // ^^^-- note the space; do NOT use Vec<Vec<int>> since the
  3033.                //       `maximal munch' rule would grab a single `>>' token
  3034.  
  3035. ==============================================================================
  3036.  
  3037. Q117: What is a `parameterized type'?
  3038. A: A parameterized type is a type that is parameterized over another value or
  3039. type.  Ex: List<int> is a type that is parameterized over another type, `int'.
  3040. Therefore the C++ rendition of parameterized types is provided by class
  3041. templates.
  3042.  
  3043. ==============================================================================
  3044.  
  3045. Q118: What is `genericity'?
  3046. A: Not to be confused with `generality' (which just means avoiding solutions
  3047. which are overly specific), `genericity' means parameterized types.  In C++,
  3048. this is provided by class templates.
  3049.  
  3050. ==============================================================================
  3051.  
  3052. Q119: How can I fake templates if I don't have a compiler that supports them?
  3053. A: The best answer is: buy a compiler that supports templates.  When this is
  3054. not feasible, the next best answer is to buy or build a template preprocessor
  3055. (ex: reads C++-with-templates, outputs C++-with-expanded-template-classes; such
  3056. a system needn't be perfect; it cost my company about three man-weeks to
  3057. develop such a preprocessor).  If neither of these is feasible, you can use the
  3058. macro preprocessor to fake templates.  But beware: it's tedious; templates are
  3059. a better solution wrt development and maintenance costs.
  3060.  
  3061. Here's how you'd declare my `Vec' example from above.  First we define `Vec(T)'
  3062. to concatenate the name `Vec' with that of the type T (ex: Vec(String) becomes
  3063. `VecString').  This would go into a header file such as Vec.h:
  3064.  
  3065.     #include <generic.h>    //to get the `name2()' macro
  3066.     #define  Vec(T)  name2(Vec,T)
  3067.  
  3068. Next we declare the class Vec(T) using the name `Vecdeclare(T)' (in general you
  3069. would postfix the name of the class with `declare', such as `Listdeclare' etc):
  3070.  
  3071.     #define Vecdeclare(T)                        \
  3072.     class Vec(T) {                            \
  3073.       int  xlen;                            \
  3074.       T*   xdata;                            \
  3075.       int  check(int i);  /*return i if in bounds else throw*/    \
  3076.     public:                                \
  3077.       int       len()             const { return xlen;     }    \
  3078.       const T&  operator[](int i) const { xdata[check(i)]; }    \
  3079.             T&  operator[](int i)       { xdata[check(i)]; }    \
  3080.                 Vec(T)(int L=10): xlen(L), xdata(new T[L]) {/*...*/}\
  3081.                ~Vec(T)()                   { delete [] xdata; }    \
  3082.     };
  3083.  
  3084. Note how each occurrence of `Vec' has the `(T)' postfixed.  Finally we set up
  3085. another macro that `implements' the non-inline member function(s) of Vec:
  3086.  
  3087.     //strangely enough this can also go into Vec.h
  3088.     #define Vecimplement(T)                        \
  3089.     int Vec(T)::check(int i)                    \
  3090.     {                                \
  3091.       if (i < 0 || i >= xlen) throw BoundsViol("Vec", i, xlen);    \
  3092.       return i;                            \
  3093.     }
  3094.  
  3095. When you wish to use a Vec-of-String and Vec-of-int, you would say:
  3096.  
  3097.     #include "Vec.h"     //pulls in <generic.h> too; see below...
  3098.     declare(Vec,String)  //`declare()' is a macro defined in <generic.h>
  3099.     declare(Vec,int)
  3100.     Vec(String) vs;      //Vec(String) becomes the single token `VecString'
  3101.     Vec(int)    vi;
  3102.  
  3103. In exactly one source file in the system, you must provide implementations for
  3104. the non-inlined member functions:
  3105.  
  3106.     #include "Vec.h"
  3107.     declare  (Vec,String)   declare  (Vec,int)   declare  (Vec,float)
  3108.     implement(Vec,String)   implement(Vec,int)   implement(Vec,float)
  3109.  
  3110. Note that types whose names are other than a single identifier do not work
  3111. properly.  Ex: Vec(char*) creates a class whose name is `Vecchar*'.  The patch
  3112. is to create a typedef for the appropriate type:
  3113.  
  3114.     #include "Vec.h"
  3115.     typedef char* charP;
  3116.     declare(Vec,charP)
  3117.  
  3118. It is important that every declaration of what amounts to `Vec<char*>' must all
  3119. use exactly the same typedef, otherwise you will end up with several equivalent
  3120. classes, and you'll have unnecessary code duplication.  This is the sort of
  3121. tedium which a template mechanism can handle for you.
  3122.  
  3123. ==============================================================================
  3124.  
  3125.         ****  PART 19 -- Nuances of particular implementations  ****
  3126.  
  3127. ==============================================================================
  3128.  
  3129. Q120: Why don't variable arg lists work for C++ on a Sun SPARCstation?
  3130. A: That is a bug in cfront 2.1.  There is a magic variable, __builtin_va_alist.
  3131. It has to be added to the end of the argument list of a varadic function, and
  3132. it has to be referenced in va_start.  This requires source modification to (a)
  3133. print `,__builtin_va_alist' on the end of the argument list, (b) pretend that
  3134. this arg was declared, and thus pass references to it, and (c) not mangle its
  3135. name in the process.
  3136.  
  3137. Here's a tiny bit more detail:
  3138. 1) when print2.c prints a varadic procedure, it should add __builtin_va_alist
  3139.    to the end. It need not declare it. Type of int to the Sun C compiler (the
  3140.    default) is fine.
  3141. 2) #define   va_start(ap,parmN)   ap = (char *)&__builtin_va_alist
  3142. 3) when find.c see this reference to __builtin_va_alist, it should construct a
  3143.    special cfront name node. When name::print sees that node it should print
  3144.    its name literally, without adding any mangling.
  3145. 4) the same trick is needed, with the name va_alist, for Ultrix/MIPS and HPUX.
  3146. 5) the net result, in generated C code, looks like:
  3147.     void var_proc (a, b, c, __builtin_va_alist)
  3148.       int a;
  3149.       float b;
  3150.       char * c;
  3151.     {
  3152.         char * val;
  3153.         val = &__builtin_va_alist;
  3154.         ...
  3155.     }
  3156.  
  3157. ==============================================================================
  3158.  
  3159. Q121: GNU C++ (g++) produces big executables for tiny programs; Why?
  3160. A: libg++ (the library used by g++) was probably compiled with debug info (-g).
  3161. On some machines, recompiling libg++ without debugging can save lots of disk
  3162. space (~1 Meg; the down-side: you'll be unable to trace into libg++ calls).
  3163. Merely `strip'ping the executable doesn't reclaim as much as recompiling
  3164. without -g followed by subsequent `strip'ping the resultant `a.out's.
  3165.  
  3166. Use `size a.out' to see how big the program code and data segments really are
  3167. rather than `ls -s a.out' which includes the symbol table.
  3168.  
  3169. ==============================================================================
  3170.  
  3171. Q122: Is there a yacc-able C++ grammar?
  3172. A: Jim Roskind is the author of a yacc grammar for C++. It's roughly compatible
  3173. with the portion of the language implemented by USL cfront 2.0.  Jim's grammar
  3174. deviates from cfront (and the ARM) in a couple of what I understand to be minor
  3175. ways.  Ultimately any deviation from a standard is unthinkable, but the number
  3176. of real programs that are interpreted differently is relatively small, so the
  3177. `consequence' of the deviation is not great.
  3178.  
  3179. I have used Jim's grammar when a grad student wrote a C++ templatizer mechanism
  3180. (reads ANSI-C++, spits out pre-templates C++), but my expertise does not
  3181. include precise knowledge of where the grammar deviates from `official'.  I
  3182. have found it to parse most things correctly, but I am aware that there are
  3183. differences.  (is that noncommittal enough? :-)
  3184.  
  3185. The grammar can be accessed by anonymous ftp from the following sites:
  3186. * ics.uci.edu (128.195.1.1) in the ftp/gnu directory (even though
  3187.   neither of the archives are GNU related) as:
  3188.         c++grammar2.0.tar.Z and byacc1.8.tar.Z
  3189. * mach1.npac.syr.edu (128.230.7.14) in the ftp/pub/C++ directory as:
  3190.         c++grammar2.0.tar.Z and byacc1.8.tar.z
  3191.  
  3192. Jim Roskind can be reached at jar@hq.ileaf.com or  ...!uunet!leafusa!jar
  3193.  
  3194. ==============================================================================
  3195.  
  3196. Q123: What is C++ 1.2?  2.0?  2.1?  3.0?
  3197. A: These are not versions of the language, but rather versions of the USL
  3198. translator, cfront.  However many people discuss these as levels of the
  3199. language as well, since each of the above versions represents additions to the
  3200. portion of the C++ language which is implemented by the compiler. When ANSI/ISO
  3201. C++ is finalized, conformance with the ANSI/ISO spec will become more important
  3202. than conformance with cfront version X.Y, but presently, cfront is acting as a
  3203. de facto standard to help coordinate the industry (although it leaves certain
  3204. features of the language unimplemented as well).
  3205.  
  3206. *VERY* roughly speaking, these are the major features:
  3207.  * 2.0 includes multiple/virtual inheritance and pure virtual functions.
  3208.  * 2.1 includes semi-nested classes and `delete [] ptr_to_array'.
  3209.  * 3.0 includes fully-nested classes, templates and `i++' vs `++i'.
  3210.  *?4.0? will include exceptions.
  3211.  
  3212. ==============================================================================
  3213.  
  3214. Q124: How does the lang accepted by cfront 3.0 differ from that accepted by 2.1?
  3215. A: USL cfront release 3.0 provides implementations of a number of features that
  3216. were previously flagged as `sorry not implemented':
  3217.  
  3218.   templates, fully nested types, prefix and postfix increment and decrement
  3219.   operators, initialization of single dimension arrays of class objects with
  3220.   ctors taking all default arguments, use of operators &&, ||, and ?: with
  3221.   expressions requiring temporaries of class objects containing destructors,
  3222.   and implicit named return values.
  3223.  
  3224. The major feature not accepted by cfront 3.0 is exceptions.
  3225.  
  3226. ==============================================================================
  3227.  
  3228. Q125: Why are exceptions going to be implemented after templates? Why not both?
  3229. A: Most C++ compiler vendors are providing templates in their present release,
  3230. but very few are providing exceptions (I know of only one).  The reason for
  3231. going slowly is that both templates and exception handling are difficult to
  3232. implement *well*. A poor template implementation will give slow compile and
  3233. link times and a poor exception handling implementation will give slow run
  3234. times.  Good implementations will not have those problems.
  3235.  
  3236. C++ compiler vendors are human beings too, and they can only get so much done
  3237. at once.  However they know that the C++ community is craving for the `whole'
  3238. language, so they'll be pushing hard to fill that need.
  3239.  
  3240. ==============================================================================
  3241.  
  3242. Q126: What was C++ 1.xx, and how is it different from the current C++ language?
  3243. A: C++ 1.2 (the version number corresponds to the release number of USL's
  3244. cfront) corresponds to Bjarne Stroustrup's first edition (`The C++ Programming
  3245. Language', ISBN 0-201-12078-X).  In contrast, the present version (3.0)
  3246. corresponds roughly to the `ARM', except for exceptions.  Here is a summary of
  3247. the differences between the first edition of Bjarne's book and the ARM:
  3248.  - A class can have more than one direct base class (multiple inheritance).
  3249.  - Class members can be `protected'.
  3250.  - Pointers to class members can be declared and used.
  3251.  - Operators `new' and `delete' can be overloaded and declared for a class.
  3252.      This allows the "assignment to `this'" technique for class specific
  3253.      specific storage management to be removed to the anachronism section
  3254.  - Objects can be explicitly destroyed.
  3255.  - Assignment and Copy-Initialization default to member-wise assignment and
  3256.      copy-initialization.
  3257.  - The `overload' keyword was made redundant and removed to the anachronism
  3258.      section.
  3259.  - General expressions are allowed as initializers for static objects.
  3260.  - Data objects can be `volatile' (new keyword).
  3261.  - Initializers are allowed for `static' class members.
  3262.  - Member functions can be `static'.
  3263.  - Member functions can be `const' or `volatile'.
  3264.  - Linkage to non-C++ program fragments can be explicitly declared.
  3265.  - Operators `->', `->*' and `,' can be overloaded.
  3266.  - Classes can be abstract.
  3267.  - Prefix and postfix application of `++' and `--' on a user-defined type
  3268.      can be distinguished.
  3269.  - Templates.
  3270.  - Exception handling.
  3271.  
  3272. ==============================================================================
  3273.  
  3274.         ****  PART 20 -- Miscellaneous technical and environmental issues  ****
  3275.  
  3276. ==============================================================================
  3277. SUBSECTION: Miscellaneous technical issues:
  3278. ==============================================================================
  3279.  
  3280. Q127: Why are classes with static data members getting linker errors?
  3281. A: Static member variables must be given an explicit definition in exactly one
  3282. module.  Ex:
  3283.  
  3284.     class X {
  3285.       //...
  3286.       static int i;  //*declare* static member X::i
  3287.       //...
  3288.     };
  3289.  
  3290. The linker will holler at you (`X::i is not defined') unless (exactly) one of
  3291. your source files has something like the following:
  3292.  
  3293.     int X::i = some_expression_evaluating_to_an_int;     //*define* X::i
  3294. or:
  3295.     int X::i;                     //define --but don't initialize-- X::i
  3296.  
  3297. The usual place to define static member variables of class `X' is file `X.C'
  3298. (or X.cpp, X.cc, X.c++, X.c or X.cxx; see question on file naming conventions).
  3299.  
  3300. ==============================================================================
  3301.  
  3302. Q128: What's the difference between the keywords struct and class?
  3303. A: The members and base classes of a struct are public by default, while in
  3304. class, they default to private.  Base classes of a struct are public by default
  3305. while they are private by default with `class' (however you should make your
  3306. base classes *explicitly* public, private, or protected).  `Struct' and `class'
  3307. are otherwise functionally equivalent.
  3308.  
  3309. ==============================================================================
  3310.  
  3311. Q129: Why can't I overload a function by its return type?
  3312.  
  3313. Ex: the compiler says the following two are an error:
  3314.     char  f(int i);
  3315.     float f(int i);
  3316.  
  3317. A: Return types are not considered when determining unique signatures for
  3318. overloading functions; only the number and type of parameters are considered.
  3319. Reason: which function should be called if the return value is ignored?  Ex:
  3320.  
  3321.     main()
  3322.     {
  3323.       f(3);  //which should be invoked??
  3324.     }
  3325.  
  3326. ==============================================================================
  3327.  
  3328. Q130: What is `persistence'?  What is a `persistent object'?
  3329. A: Loosely speaking, a persistent object is one that lives on after the
  3330. program which created it has stopped.  Persistent objects can even outlive
  3331. various versions of the creating program, can outlive the disk system, the
  3332. operating system, or even the hardware on which the OS was running when
  3333. they were created.
  3334.  
  3335. The challenge with persistent objects is to effectively store their method
  3336. code out on secondary storage along with their data bits (and the data bits
  3337. and method code of all subobjects, and of all their subobjects, etc).  This
  3338. is non-trivial when you have to do it yourself.  In C++, you have to do it
  3339. yourself.  C++/OO databases can help hide the mechanism for all this.
  3340.  
  3341. ==============================================================================
  3342. SUBSECTION: Miscellaneous environmental issues:
  3343. ==============================================================================
  3344.  
  3345. Q131: Is there a TeX or LaTeX macro that fixes the spacing on `C++'?
  3346. A: Yes, here are two:
  3347.  
  3348. \def\CC{C\raise.22ex\hbox{{\footnotesize +}}\raise.22ex\hbox{\footnotesize +}}
  3349.  
  3350. \def\CC{{C\hspace{-.05em}\raisebox{.4ex}{\tiny\bf ++}}}
  3351.  
  3352. ==============================================================================
  3353.  
  3354. Q132: Where can I access C++2LaTeX, a LaTeX pretty printer for C++ source?
  3355. A: Here are a few ftp locations:
  3356.  
  3357. Host aix370.rrz.uni-koeln.de   (134.95.80.1) Last updated 15:41 26 Apr 1991
  3358.     Location: /tex
  3359.       FILE      rw-rw-r--     59855  May  5  1990   C++2LaTeX-1.1.tar.Z
  3360. Host utsun.s.u-tokyo.ac.jp   (133.11.11.11) Last updated 05:06 20 Apr 1991
  3361.     Location: /TeX/macros
  3362.       FILE      rw-r--r--     59855  Mar  4 08:16   C++2LaTeX-1.1.tar.Z
  3363. Host nuri.inria.fr   (128.93.1.26) Last updated 05:23  9 Apr 1991
  3364.     Location: /TeX/tools
  3365.       FILE      rw-rw-r--     59855  Oct 23 16:05   C++2LaTeX-1.1.tar.Z
  3366. Host iamsun.unibe.ch   (130.92.64.10) Last updated 05:06  4 Apr 1991
  3367.     Location: /TeX
  3368.       FILE      rw-r--r--     59855  Apr 25  1990   C++2LaTeX-1.1.tar.Z
  3369. Host iamsun.unibe.ch   (130.92.64.10) Last updated 05:06  4 Apr 1991
  3370.     Location: /TeX
  3371.       FILE      rw-r--r--     51737  Apr 30  1990
  3372.       C++2LaTeX-1.1-PL1.tar.Z
  3373. Host tupac-amaru.informatik.rwth-aachen.de   (192.35.229.9) Last updated 05:07 18 Apr 1991
  3374.     Location: /pub/textproc/TeX
  3375.       FILE      rw-r--r--     72957  Oct 25 13:51  C++2LaTeX-1.1-PL4.tar.Z
  3376. Host wuarchive.wustl.edu   (128.252.135.4) Last updated 23:25 30 Apr 1991
  3377.     Location: /packages/tex/tex/192.35.229.9/textproc/TeX
  3378.       FILE      rw-rw-r--     49104  Apr 10  1990   C++2LaTeX-PL2.tar.Z
  3379.       FILE      rw-rw-r--     25835  Apr 10  1990   C++2LaTeX.tar.Z
  3380. Host tupac-amaru.informatik.rwth-aachen.de   (192.35.229.9) Last updated 05:07 18 Apr 1991
  3381.     Location: /pub/textproc/TeX
  3382.       FILE rw-r--r-- 74015  Mar 22 16:23 C++2LaTeX-1.1-PL5.tar.Z
  3383.     Location: /pub
  3384.       FILE rw-r--r-- 74015  Mar 22 16:23 C++2LaTeX-1.1-PL5.tar.Z
  3385. Host sol.cs.ruu.nl   (131.211.80.5) Last updated 05:10 15 Apr 1991
  3386.     Location: /TEX/TOOLS
  3387.       FILE      rw-r--r--     74015  Apr  4 21:02x   C++2LaTeX-1.1-PL5.tar.Z
  3388. Host tupac-amaru.informatik.rwth-aachen.de (192.35.229.9) Last updated 05:07 18 Apr 1991
  3389.     Location: /pub/textproc/TeX
  3390.       FILE      rw-r--r--      4792  Sep 11  1990 C++2LaTeX-1.1-patch#1
  3391.       FILE      rw-r--r--      2385  Sep 11  1990 C++2LaTeX-1.1-patch#2
  3392.       FILE      rw-r--r--      5069  Sep 11  1990 C++2LaTeX-1.1-patch#3
  3393.       FILE      rw-r--r--      1587  Oct 25 13:58 C++2LaTeX-1.1-patch#4
  3394.       FILE      rw-r--r--      8869  Mar 22 16:23 C++2LaTeX-1.1-patch#5
  3395.       FILE      rw-r--r--      1869  Mar 22 16:23 C++2LaTeX.README
  3396. Host rusmv1.rus.uni-stuttgart.de   (129.69.1.12) Last updated 05:13 13 Apr 1991
  3397.     Location: /soft/tex/utilities
  3398.       FILE      rw-rw-r--    163840  Jul 16  1990   C++2LaTeX-1.1.tar
  3399.  
  3400. ==============================================================================
  3401.  
  3402. Q133: Where can I access `tgrind', a pretty printer for C++/C/etc source?
  3403. A: `tgrind' reads the file to be printed and a command line switch to see what
  3404. the source language is.  It then reads a language definition database file and
  3405. learns the syntax of the language (list of keywords, literal string delimiters,
  3406. comment delimiters, etc).
  3407.  
  3408. `tgrind' usually comes with the public distribution of TeX and LaTeX.  Look in
  3409. the directory:
  3410.     ...tex82/contrib/van/tgrind
  3411.  
  3412. A more up-to-date version of tgrind by Jerry Leichter can be found on:
  3413.     venus.ycc.yale.edu in [.TGRIND]
  3414.  
  3415. ==============================================================================
  3416.  
  3417. Q134: Is there a C++-mode for GNU emacs?  If so, where can I get it?
  3418. A: Yes, there is a C++-mode for GNU emacs.  You can get it via:
  3419.  
  3420. c++-mode-2 (1.0)  87-12-08
  3421.      Bruce Eckel,Thomas Keffer, <eckel@beluga.ocean.washington.edu,uw-beaver!beluga!eckel,keffer@sperm.ocean.washington.edu>
  3422.      archive.cis.ohio-state.edu:/pub/gnu/emacs/elisp-archive/as-is/c++-mode-2.el.Z
  3423.  
  3424.      Another C++ major mode.
  3425. c++-mode      89-11-07
  3426.      Dave Detlefs, et al, <dld@cs.cmu.edu>
  3427.      archive.cis.ohio-state.edu:/pub/gnu/emacs/elisp-archive/modes/c++-mode.el.Z
  3428.  
  3429.      C++ major mode.
  3430. c++          90-02-01
  3431.      David Detlefs, Stewart Clamen, <dld@f.gp.cs.cmu.edu,clamen@cs.cmu.edu>
  3432.      archive.cis.ohio-state.edu:/pub/gnu/emacs/elisp-archive/modes/c++.el.Z
  3433.      C++ code editing commands for Emacs
  3434.  
  3435. c-support (46)      89-11-04
  3436.      Lynn Slater, <lrs@indetech.com>
  3437.      archive.cis.ohio-state.edu:/pub/gnu/emacs/elisp-archive/misc/c-support.el.Z
  3438.      Partial support for team C/C++ development.
  3439.  
  3440. ==============================================================================
  3441.  
  3442. Q135: What is `InterViews'?
  3443. A: A non-proprietary toolkit for graphic user interface programming in C++,
  3444. developed by Mark Linton and others when he was at Stanford.  Unlike C++
  3445. wrappers for C libraries such as Motif, InterViews is a true object library.
  3446. Commercially maintained versions are available from Quest, while freely
  3447. redistributable versions (running on top of X) from interviews.stanford.edu (an
  3448. ftp site).  Copies of this are (were?) distributed with the regular X
  3449. distribution.  Other sources of information include comp.windows.interviews,
  3450. which has its own FAQ.
  3451.  
  3452. ==============================================================================
  3453.  
  3454. Q136: Where can I get OS-specific questions answered (ex:BC++,DOS,Windows,etc)?
  3455. A: see comp.os.msdos.programmer, BC++ and Zortech mailing lists, BC++ and
  3456.    Zortech bug lists, comp.windows.ms.programmer, comp.unix.programmer, etc.
  3457.  
  3458. You can subscribe to the BC++ mailing list by sending email to:
  3459. |    To: listserv@ucf1vm.cc.ucf.edu   <---or LISTSERV@UCF1VM.BITNET
  3460. |    Subject: SUB TCPLUS-L
  3461. |    Reply-to: you@your.email.addr    <---ie: put your return address here
  3462.  
  3463. The BC++ bug report is available via anonymous ftp from sun.soe.clarkson.edu
  3464. [128.153.12.3] from the file ~ftp/pub/Turbo-C++/bug-report
  3465. (also, I post it on comp.lang.c++ on the first each month).
  3466.  
  3467. Relevant email addresses:
  3468.     ztc-list@zortech.com          General requests and discussion
  3469.     ztc-list-request@zortech.com  Requests to be added to ztc-list
  3470.     ztc-bugs@zortech.com          For _short_ bug reports
  3471.  
  3472. ==============================================================================
  3473.  
  3474. Q137: Why does my DOS C++ program says `Sorry: floating point code not linked'?
  3475. A: The compiler attempts to save space in the executable by not including the
  3476. float-to-string format conversion routines unless they are necessary, and
  3477. sometimes does not recognize some code that does require it. Taking the address
  3478. of a float in an argument list of a function call seems to trigger it, but
  3479. taking the address of a float element of a struct may fool the compiler.  A
  3480. "%f" in a printf/scanf format string doesn't trigger it because format strings
  3481. aren't examined at compile-time.
  3482.  
  3483. You can fix it by (1) using <iostream.h> instead of <stdio.h>, or (2) by
  3484. including the following function definition somewhere in your compilation (but
  3485. don't call it!):
  3486.     static void dummyfloat(float *x) { float y; dummyfloat(&y); }
  3487.  
  3488. See question on stream I/O for more reasons to use <iostream.h> vs <stdio.h>.
  3489.  
  3490. =============================================================================ed
  3491. --
  3492. Marshall Cline
  3493. --
  3494. Marshall P. Cline, Ph.D. / Paradigm Shift, Inc / One Park St/Norwood, NY 13668
  3495. cline@parashift.com / 315-353-6100 / FAX: 315-353-6110
  3496.  
  3497.  
  3498.